2017-08-26 71 views
0

我有一個使用python子進程和一個隊列的單個使用者的典型多個生產者。 消費者回調到另一個對象。雖然該對象與所有子進程共享,但子進程完成後,該對象的更改將丟失。子進程和在回調中共享自我對象

下面的代碼:

from multiprocessing import Process, Queue 
import random 
import time 

class Manager(object): 
    def __init__(self): 
     self.queue = Queue() 

    def consume(self, call_back): 
     while True: 
      task = self.queue.get() 
      if task is None: 
       self.queue.close() 
       break 
      time.sleep(0.05) 
      call_back(task) 
      print("Queue got task: {}.".format(task)) 

    def produce(self, value): 
     time.sleep(random.uniform(0.1, 1.0)) 
     task = "TSK {}".format(value) 
     self.queue.put(task) 


    def start(self, call_back, n_tasks=10): 

     consumer = Process(target=self.consume, args=(call_back,)) 
     consumer.start() 

     workers = [Process(target=self.produce,args=(i,)) 
      for i in range(n_tasks)] 

     for w in workers: 
      w.start() 
     for w in workers: 
      w.join() 

     self.queue.put(None) 
     consumer.join() 


class Display(object): 
    def __init__(self): 
     self.tasks = [] 

    def display_tasks(self, n_tasks=10): 
     def add_task(task): 
      self.tasks.append(task) 
      print("Dislaying tasks so far: {}".format(self.tasks)) 
     Manager().start(add_task, n_tasks) 
     print("Total tasks: {}".format(self.tasks)) 


Display().display_tasks(5) 

輸出是:

Dislaying tasks so far: ['TSK 3'] 
Queue got task: TSK 3. 
Dislaying tasks so far: ['TSK 3', 'TSK 4'] 
Queue got task: TSK 4. 
Dislaying tasks so far: ['TSK 3', 'TSK 4', 'TSK 2'] 
Queue got task: TSK 2. 
Dislaying tasks so far: ['TSK 3', 'TSK 4', 'TSK 2', 'TSK 0'] 
Queue got task: TSK 0. 
Dislaying tasks so far: ['TSK 3', 'TSK 4', 'TSK 2', 'TSK 0', 'TSK 1'] 
Queue got task: TSK 1. 
Total tasks: [] 

我期待:

Total tasks: ['TSK 3', 'TSK 4', 'TSK 2', 'TSK 0', 'TSK 1'] 

任何想法如何可以完成此而不:

class Display(object): 
    def __init__(self): 
     manager = Manager() 
     self.tasks = manager.list() 

事實上,在此使用QTableWidget,並在表中的每個條目的實際情況是QTableWidgetItem ....

這是真正的回調函數(data_set_tableQTableWidget):

def _add_item(data): 
     row = dc.size() 
     self._content.data_set_table.insertRow(row) 
     for i in range(len(data)): 
      if data[i] is not None: 
       item = QtGui.QTableWidgetItem(str(data[i])) 
       item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) 
       self._content.data_set_table.setItem(row, i, item) 

回答

0

答案似乎是使用Manager。我將刪除它回答不qith PyQt工作:

從多處理導入過程中,隊列,經理 從multiprocessing.managers導入BaseManager
進口隨機 進口時間

class Scheduler(object): 
    def __init__(self): 
     self.queue = Queue() 

    def consume(self, call_back): 
     while True: 
      task = self.queue.get() 
      if task is None: 
       self.queue.close() 
       break 
      time.sleep(0.05) 
      print("Queue got task: {}.".format(task)) 
      call_back(task) 

    def produce(self, value): 
     time.sleep(random.uniform(0.1, 1.0)) 
     task = "TSK {}".format(value) 
     self.queue.put(task) 


    def start(self, call_back, n_tasks=10): 

     consumer = Process(target=self.consume, args=(call_back,)) 
     consumer.start() 

     workers = [Process(target=self.produce,args=(i,)) 
      for i in range(n_tasks)] 

     for w in workers: 
      w.start() 
     for w in workers: 
      w.join() 

     self.queue.put(None) 
     consumer.join() 

class CustomTable(object): 
    def __init__(self): 
     self.contents = [] 

    def addItem(self, item): 
     self.contents.append(item) 

    def display(self): 
     print(self.__repr__) 

    def __repr__(self): 
     res = 80*"-" + "\n" + str(self.contents) + "\n" + 80*"-" + "\n" 
     return res 

class CustomTableManager(BaseManager): 
    pass 

CustomTableManager.register('CustomTable', CustomTable, exposed = ['contents', 'addItem', 'display', '__repr__']) 

customTableManager = CustomTableManager() 
customTableManager.start() 

class Display(object): 
    def __init__(self): 
     # self.tasks = CustomTable() 
     self.tasks = customTableManager.CustomTable() 

    def display_tasks(self, n_tasks=10): 
     def add_task(task): 
      self.tasks.addItem(task) 
      print("Dislaying tasks so far:\n{}".format(self.tasks)) 
     Scheduler().start(add_task, n_tasks) 
     print("Total tasks:\n{}".format(self.tasks)) 

Display().display_tasks(5)