Python多重处理:join()/ task_done()是否可以与并发进程配合使用?

时间:2018-11-08 15:56:57

标签: python queue multiprocessing

我一直在抓取网络,下载图像,对其进行处理,同时将其全部记录在MySQL中。我使用SyncManager创建服务器并在其中创建可连接队列。

我有一个用于服务器,Scraper,下载器,图像处理器和SQL处理器的脚本。他们每个人都有他们专用的可加入队列。我同时运行所有脚本(每个脚本有多个实例-为了提高速度),我需要同步所有脚本的输出,因此在需要时使用join()和task_done()。

我的问题如下:假设我启动每个脚本的10个实例。 (以Downloader为例:) Downloader的一个实例的join()是否等待实例-并且仅该实例-放入ImageProcessor? (虽然其他下载程序也会加载imgProc的队列)我希望如此,但是我想确定。

我正在尝试测试它,但是很难看清所有输出。所以我认为我可以使用专家的确认(我是多处理的新手)。谢谢!

代码如下:
这是我的服务器的样子:

from multiprocessing.managers import SyncManager
from multiprocessing import JoinableQueue

class QueueManager(SyncManager):
    pass

class Server(Process):
    def __init__(self, ip, port, authkey):
        super(Server, self).__init__()
        self.ip = ip
        self.port = port
        self.authkey = authkey

    def make_server_manager(self):
        q_search = JoinableQueue() #input for the scraper
        q_imgProc = JoinableQueue() #input for the Image Processor
        q_sql = JoinableQueue() #input queue to the sqlServer
        q_download = JoinableQueue() #queue for the Downloader
        QueueManager.register('q_search', callable=lambda: q_search)
        QueueManager.register('q_imgProc', callable=lambda: q_imgProc)
        QueueManager.register('q_sql', callable=lambda: q_sql)
        QueueManager.register('q_download', callable=lambda: q_download)
        QueueManager.register('rootFolder', callable = lambda:"some dir")
        manager = QueueManager(address=(self.ip, self.port), authkey=self.authkey)
        print('Server started at port ' + str(self.port))
        return manager

if __name__ == "__main__":
    ip = '127.0.0.1'
    port = 24487
    authkey = b'abc'

    s = Server(ip,port,authkey)
    manager = s.make_server_manager()
    s = manager.get_server()
    s.serve_forever()

其他脚本(即下载器)的外观如下:

from multiprocessing.managers import SyncManager

class QueueManager(SyncManager):
    pass

class Downloader():

    def __init__(self,ip,port,authkey):
        [Initialize all the variables as they are defined in the Server]

     def SomeFctThatDoesStuff(self,...):
         [work]

         #send sth to the Image Processor
         For image in images:
             self.q_imgProc.put('message')
         self.q_imgProc.join()

if __name__ == "__main__":
    ip = '127.0.0.1'
    port = 24487
    authkey = b'abc'
    downloader = Downloader(ip, port, authkey)

    while True:
        rcvd = downloader.q_download.get()
        downloader.q_download.task_done()

很显然,imgProc和所有其他相关进程的末尾也有一个task_done() (python 3.6)

0 个答案:

没有答案