Python多处理数据交换

时间:2018-03-11 17:29:47

标签: python multithreading python-2.7

我试图在同一进程中的两个线程之间传递数据,主线程在一个单独的类中生成一个新线程。我试图使用multiprocessing.Queue对象传递字符串。

我不明白为什么第二个线程没有看到队列中的数据。

mainClass.py

if(__name__ == '__main__'):
    # Create the threads
    itemInterestThread = NewItemInterestHelper("Item Interest Thread")

    # Start the Item Interest Thread
    itemInterestThread.run()

    time.sleep(1)
    print "Adding item\n"
    itemInterestThread.addToQueue("Neat Thing")
    time.sleep(1)
    print "Adding item\n"
    itemInterestThread.addToQueue("Neat Thing2")

    print "Sleeping for 5 seconds"
    time.sleep(5)

NewItemInterestHelper.py

import multiprocessing
import time

class NewItemInterestHelper:
    # Class Variables
    __itemsQueue = multiprocessing.Queue()
    __itemMutex = multiprocessing.Lock()
    __pool = multiprocessing.Process()

    def __init__(self, name):
        self.name = name

    def run(self):
        self.__pool = multiprocessing.Process(target=self.dowork)
        self.__pool.start()

    def dowork(self):
        while True:
            self.__itemMutex.acquire()
            if not self.__itemsQueue.empty():
                print "Got " + self.__itemsQueue.get() + "\n"

            self.__itemMutex.release()
            time.sleep(1)

    def addToQueue(self, queueAddition):
        self.__itemMutex.acquire()
        self.__itemsQueue.put(queueAddition)
        self.__itemMutex.release()

1 个答案:

答案 0 :(得分:1)

首先,您在问题中混淆了线程和多处理。它们不是同一件事。如果你更新你的问题更清楚,那可能会很好。线程在同一过程中完成(至少在概念上),因此将共享所有全局变量和状态。在进行多处理时,这些过程将彼此独立,因此共享全局变量和状态。相反,每个进程都将实例化自己的进程。

因此,您的类变量(实际上是全局变量)将不会在主进程和辅助进程之间共享。不同的进程将拥有自己的队列和锁,从头开始创建。

但是,如果锁和队列属于对象而不是类,则在生成辅助进程时将复制它们。通过这种方式,他们将分享足够的内部成员来做你想做的事情。因此,如果您更改NewItemInterestHelper以使锁定和队列成为动态对象的一部分,那么它应该可以工作:

class NewItemInterestHelper:
    # Removing all class variables

    def __init__(self, name):
        self.__itemsQueue = multiprocessing.Queue()
        self.__itemMutex = multiprocessing.Lock()
        # removing self.__pool since it is just overwritten
        # by the run method

        self.name = name

    # Rest of class follows...

现在,由于队列和辅助进程中的锁是从队列的副本和主进程中的锁创建的。这样他们将分享足够的内部内容,分别被认为是相同的队列和锁定。

另一方面,我认为这是一个简化的例子,因为如上所述,根本不需要互斥锁/锁。没有必要保护队列的写入不被队列中的读取保护,因为它会由底层系统自动处理。