code: def producer_consumer(producer, consumer, addr='tcp://127.0.0.1',
                        port=None, context=None):
      
      context_created = False
      if context is None:
          context_created = True
          context = zmq.Context()
      try:
          consumer_socket = context.socket(zmq.PULL)
          if port is None:
              port = consumer_socket.bind_to_random_port(addr)
          try:
              process = _spawn_producer(producer, port)
              result = consumer(consumer_socket)
          finally:
              process.terminate()
          return result
      finally:
          # Works around a Python 3.x bug.
          if context_created:
              context.destroy()
docs: A producer-consumer pattern.
  
      Parameters
      ----------
      producer : callable
          Callable that takes a single argument, a handle
          for a ZeroMQ PUSH socket. Must be picklable.
      consumer : callable
          Callable that takes a single argument, a handle
          for a ZeroMQ PULL socket.
      addr : str, optional
          Address to which the socket should connect. Defaults
          to localhost ('tcp://127.0.0.1').
      port : int, optional
          The port on which the consumer should listen.
      context : zmq.Context, optional
          The ZeroMQ Context to use. One will be created otherwise.
  
      Returns
      -------
      result
          Passes along whatever `consumer` returns.
  
      Notes
      -----
      This sets up a PULL socket in the calling process and forks
      a process that calls `producer` on a PUSH socket. When the
      consumer returns, the producer process is terminated.
  
      Wrap `consumer` or `producer` in a `functools.partial` object
      in order to send additional arguments; the callables passed in
      should expect only one required, positional argument, the socket
      handle.