将生产者流程中的变量共享到所有消费者流程

时间:2015-12-11 14:45:01

标签: python multithreading events multiprocessing

应用程序代表流分割器 - 生产者进程正在接收数据流,而多个消费者进程(客户端连接)将接收到的数据发送(传递)给连接的客户端。

我已经为Condition Variable发现了sample code(它使用的是multithreading,但它也应该适用于multiprocessing)并重构它以便它不会在消费者流程中弹出项目。这就是我期望其他消费者流程能够重用它并将相同数据重新发送到连接的客户端的方式。一旦所有消费者流程完成发送,我就从缓冲区数组中删除item[0]。但这不起作用,因为进程没有以可预测的顺序执行。

1. Receive new data - Producer process
2. Send received data - Consumer process [1]
3. Send received data - Consumer process [2]
...
n. Send received data - Consumer process [n]
Loop everything.

生成器进程通常会在所有Consumer进程检索item[0]并发送之前删除item[0]

我想一种可能的解决方案是为每个使用者进程使用单独的Queue(),并在生产者进程中使用单独的Event()来填充这些单独的队列。

是否可以使用import threading import time # A list of items that are being produced. Note: it is actually # more efficient to use a collections.deque() object for this. items = [] # A condition variable for items items_cv = threading.Condition() # A producer thread def producer(): print "I'm the producer" for i in range(30): with items_cv: # Always must acquire the lock first items.append(i) # Add an item to the list items_cv.notify() # Send a notification signal time.sleep(1) items.pop(0) # Pop item remove it from the "buffer" # A consumer thread def consumer(): print "I'm a consumer", threading.currentThread().name while True: with items_cv: # Must always acquire the lock while not items: # Check if there are any items items_cv.wait() # If not, we have to sleep # x = items.pop(0) # Pop an item off x = items[0] print threading.currentThread().name,"got", x time.sleep(5) # Launch a bunch of consumers cons = [threading.Thread(target=consumer) for i in range(10)] for c in cons: c.setDaemon(True) c.start() # Run the producer producer() 通知消费者进程新数据到达,然后独立地从其他消费者进程传递该数据而没有队列?

如果使用队列是最佳解决方案,是否可以只使用一个队列并保留新数据,直到所有消费者进程完成发送?

我可以接受任何建议,因为我不确定最好的方法是什么。

Dim txt1(DispBox.Text.Split(" ").Length) As String
Dim txt2(DispBox2.Text.Split(" ").Length) As String
txt1 = DispBox.Text.Split(" ")
txt2 = DispBox2.Text.Split(" ")
Dim diff1 As String = "" 'Differences between 1 and 2
Dim diff2 As String = "" 'Differences between 2 and 1
Dim diffPosition As Integer ' Set where begin to find and select in RichTextBox

diffPosition = 1 ' Initialize
For Each diff As String In txt1
  If Array.IndexOf(txt2, diff.ToString) = -1 Then
    diff1 += diff.ToString & "  "
    With DispBox
      .Find(diff, diffPosition, RichTextBoxFinds.None) ' Find and select diff in RichTextBox1 starting from position diffPosition in RichtextBox1
      .SelectionFont = New Font(.Font, FontStyle.Bold) ' Set diff in Bold
      .SelectionColor = Color.Blue ' Set diff in blue instead of black
      .SelectionBackColor = Color.Yellow ' highlight in yellow
    End With
  End If
  diffPosition = diffPosition + Len(diff) ' re-Initialize diffPostion to avoid to find and select the same text present more than once
Next

DispBox3.Visible = True
DispBox3.Text = diff1

1 个答案:

答案 0 :(得分:0)

解决此问题的最简单方法是为每个客户端提供Queue。在我的acceptor(监听器)函数中,我有这种代码安静,它为每个传入连接创建缓冲区/队列。

        buffer = multiprocessing.Queue()
        self.client_buffers.append(buffer)
        process = multiprocessing.Process(name=procces_name,
                                          target=self.stream_handler,
                                          args(conn, address, buffer))
        process.daemon = True
        process.start()

在主(生产者)线程中,一旦新数据到达,就会填充每个队列。

while True:
    data = sock.recv(2048)
    if not data: break
    for buffer in self.client_buffers:
        buffer.put(data)

每个消费者流程独立发送数据

if not buffer.empty():
   connection.sendall(buffer.get())