0

Producer Different Thread with its own SynchronizedBlockingQueue. Each producer put there message into its own queue.

Consumer

Different Thread which will get message from either from any one of queue and start process.

Now for communicating producer and consumer, we need broker. which may be bottleneck. Is there any other way consumer get one message form any producer and start process.

  • You would need to expose each producer's queues, and have each consumer poll every producer in the crudest scenario. I'd rather use a broker because the architecture will be more elegant (also easier to use), and here if there is a bottleneck, most of the brokers (rabbitmq, activemq...etc) supports a distributed architecture. Without that you will have to do it yourself. – Adonis Jul 03 '17 at 10:55

1 Answers1

0

Since you did not specify a language, I thought I would provide a general example using the Ada programming language. This example has the consumer simply print the messages from the producers, but it gives the producer-consumer architecture you described.

with Ada.Task_Identification; use Ada.Task_Identification;

package Multiple_Producer is
   type Producer_Message is private;

   protected type Buffer is
      entry Set_Message (Item : in Producer_Message);
      entry Get_Message (Item : out Producer_Message);
   private
      Msg    : Producer_Message;
      Is_New : Boolean := False;
   end Buffer;
   type Buf_Alias is access all Buffer;
   type Buf_Array is array (Positive range <>) of aliased Buffer;
   type Buf_Access is access all Buf_Array;

   task type Producer is
      entry Set_Buffer (Item : Buf_Alias);
      entry Stop;
   end Producer;


   task Consumer is
      entry Set_Buffers (Item : Buf_Access);
      entry Stop;
   end Consumer;

private
   type Producer_Message is record
      the_Task : Task_Id;
      Value    : Integer;
   end record;
end Multiple_Producer;

with Ada.Text_IO; use Ada.Text_IO;

package body Multiple_Producer is

   --------------
   -- Producer --
   --------------

   task body Producer is
      Message : Producer_Message := (Current_Task, 0);
      The_Buf : Buf_Alias;
   begin
      accept Set_Buffer(Item : in Buf_Alias) do
         The_Buf := Item;
      end Set_Buffer;

      loop
         select
            accept Stop;
            exit;
         else
            delay 0.01;
            The_Buf.Set_Message(Message);
            Message.Value := Message.Value + 1;
         end select;
      end loop;
   end Producer;

   --------------
   -- Consumer --
   --------------

   task body Consumer is
      Message : Producer_Message;
      Buffers : Buf_Access;
   begin
      accept Set_Buffers(Item : Buf_Access) do
         Buffers := Item;
      end Set_Buffers;

      loop
         select
            accept Stop;
            exit;
         else
            -- Poll the buffers
            for I in Buffers'Range loop
               select
                  Buffers(I).Get_Message(Message);
                  Put_Line(Image(Message.The_Task) & ": " &
                             Integer'Image(Message.Value));
               or
                  delay 0.001;
               end select;
            end loop;
         end select;
      end loop;
   end Consumer;

   ------------
   -- Buffer --
   ------------

   protected body Buffer is

      -----------------
      -- Set_Message --
      -----------------

      entry Set_Message (Item : in Producer_Message) when not Is_New is
      begin
         Msg := Item;
         Is_New := True;
      end Set_Message;

      -----------------
      -- Get_Message --
      -----------------

      entry Get_Message (Item : out Producer_Message) when Is_New is
      begin
         Item := Msg;
         Is_New := False;
      end Get_Message;

   end Buffer;

end Multiple_Producer;

with Multiple_Producer; use Multiple_Producer;

procedure Main is
   subtype Producer_Range is Positive range 1..5;
   The_Producers : array(Producer_Range) of Producer;
   The_Buffers   : Buf_Access := new Buf_Array(Producer_Range); 
begin
   for I in Producer_Range loop
      The_Producers(I).Set_Buffer(The_Buffers(I)'Access);
   end loop;
   Consumer.Set_Buffers(The_Buffers);
   delay 4.0;
   for P of The_Producers loop
      P.Stop;
   end loop;
   Consumer.Stop;
end Main;
Jim Rogers
  • 4,822
  • 1
  • 11
  • 24