如何在Python中创建进程间数据结构?

4

我可以帮忙翻译这段内容。它涉及到IT技术。要翻译的是一个包含字典的列表,名称为requestRoster。每个字典中包含了一些项目,例如'requestTime'和'thisURL'等等。例如:

[
{'thisURL': 'http://localhost/bikes', 'requestTime': datetime.datetime(2012, 10, 18, 0, 41, 34)}, 
{'thisURL': 'http://localhost/clothing', 'requestTime': datetime.datetime(2012, 10, 18, 0, 41, 35)}
]

我正在使用multiprocessing.Process来生成一个新进程以发出每个请求。
我希望每个进程都能更新requestRoster,将'response'项目添加到每个请求中。
我该怎么做?
我尝试使用multiprocessing.Manager()来创建manager.list()和manager.Namespace()。但是,我认为这是不行的,因为这里有一个问题:http://docs.python.org/library/multiprocessing.html#multiprocessing.managers.SyncManager.list 我认为我可以使用multiprocessing.Lock()来:
- 获取互斥锁 - 在进程内部复制requestRoster - 修改本地化的requestRoster - 用本地化的request roster覆盖全局化的request roster - 释放互斥锁
但这似乎有点繁琐,我想知道是否有更简单的方法。异步回调会很好。

你的工人需要从值班表中阅读,还是只需对其进行响应?根据您的描述,似乎一个简单的队列或甚至是在调度程序和每个工人之间连接的管道都可以用来推送响应数据,然后调度程序可以负责将响应记录到呼叫历史记录中的正确条目。 - Silas Ray
好的,队列。所以调度程序分派任务;工作进程执行任务;工作进程将结果添加到队列中;调度程序考虑队列并出队响应。类似于这样吗?我很喜欢...唯一让我担心的是,当需要同时分派几百个请求时,调度程序已经不堪重负了,不应该再让它承担更多的责任。我认为有充分的理由让工作进程访问“全局”数据结构,并且让工作进程完成所有工作,包括更新。 - dave
日志记录过程是否也会遇到与HTTP工作进程相同的进程间写入问题呢?也就是说,它将无法更新主请求列表。但在所有内容都已分派后,我可以排除队列中的内容。确实需要划分组件。 - dave
最终需要对名册做什么?调度程序可以打开一个管道或队列到记录器,为每个工作进程创建一个管道,将该管道推送到记录器以便连接,然后工作进程可以将其响应推送到调度程序设置的管道中。我认为这应该可以工作,除非您需要其他工作进程/进程同时从日志中读取。 - Silas Ray
花名册将在Qt网格中显示(某种形式),结果将实时显示。 - dave
显示剩余3条评论
3个回答

2

如果可以的话,最好避免使用共享内存结构。在这里,没有理由让进程自己写入字典列表 - 相反,您可以使主进程负责此操作,并将URL获取任务分配给进程。

我喜欢使用concurrent.futures.<Process|Thread>PoolExecutor来处理这种任务。


谢谢您的建议,但我使用的是Python 2.7.3,所以我不认为我可以使用concurrent.futures(虽然它看起来很好)。我认为最好的方法是子进程(或者你想叫它们什么)写入字典列表,因为主进程已经忙于工作 - 比如,当需要同时处理数百个请求时。 - dave

0
我认为这种方法对你应该有效:
调度程序:
create logger_queue
create logger process, initialize with logger_queue
for each request
    create worker_pipe
    create worker process, initialize with send end of worker_pipe
    push receive end of worker_pipe over logger_queue

工人:

make request
push response over connection

日志记录器:

while True
    for connection on logger_queue
        create new element in logging list
        link connection to new logging list element
    for each open connection
        poll for message
        if message
            store message to log
            close connection

记录器进程还可以运行任何输出例程,因此您甚至不必担心是否有另一个进程从已记录的数据集中读取。请注意,上面提到的连接是指 multiprocessing.Connection


非常感謝您提供的輸入,但考慮到我只是想將數據結構全球化,這非常複雜。 我不想製作隊列、管道和日誌記錄器(更多問題),我只想讓工人能夠更新主進程中的數據...(但再次感謝您的輸入,這是受歡迎的) - dave
共享数据结构非常复杂,有很多开销和陷阱。如果可以避免使用它们,最好不要使用。如果您只想在主进程中完成所有操作,请将记录器逻辑放在调度程序中并切掉队列。我这样拆分是因为您说您希望调度程序精简。 - Silas Ray

0

我通过使用线程而不是多进程来实现这一点。因为工作线程与调度程序在同一个进程中,所以它们可以更新请求花名册。


线程对于你来说可能是可以的,因为你的工作人员是I/O绑定的,但要注意,如果你遇到CPU绑定的性能问题,GIL将会强制你改用多进程。 - Silas Ray

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接