进程和线程之间共享和更新列表
Posted
技术标签:
【中文标题】进程和线程之间共享和更新列表【英文标题】:Sharing and Updating List between Processes and Threads 【发布时间】:2022-01-16 14:48:36 【问题描述】:尝试在主进程 - 主线程和子进程 - 子线程之间共享和更新列表。目前看来,主进程和主线程共享一个列表副本的更新,而子进程和子线程共享另一个列表副本。我原以为经理会允许在所有 4 人之间共享列表。非常感谢任何帮助。
代码:
from multiprocessing import Process, Manager
import time
import threading
def main_thread(l):
while True:
l[0][5] += 1
print("main_thread:", l)
time.sleep(6)
def sub_thread(l):
while True:
l[1][5] += 1
print("sub_thread:", l)
time.sleep(7)
def sub_process(l):
#create a sub_thread to update l[1][5]
trading_thread = threading.Thread(target=sub_thread, args=(l,))
trading_thread.start()
time.sleep(1)
while True:
l[0][6] += 1
print("sub_process:", l)
time.sleep(9)
def main_process():
#create a thread to increment l[0][5]
trading_thread = threading.Thread(target=main_thread, args=(l,))
trading_thread.start()
time.sleep(1)
#Create a sub_process to start a sub_process and increment l[0][6]
p = Process(target=sub_process, args=(l,))
p.start()
time.sleep(1)
#I need this while loop to run as well:
while True:
l[0][7] += 1
print("main_process: ", l)
time.sleep(8)
p.join() #this could be a problem - we never get to this because sub process is never supposed to finish,
#I tried to put this before the 'While' loop above but then the loop never gets triggered.
if __name__ == '__main__':
manager = Manager()
l = manager.list()
l = [['LACE', 1639144800000, 1.157857245, '9:00 December 10, 2021', 'True', 0, 0, 0],
['ARKER', 1639109835404, 0.0, '10:00 December 10, 2021', 'True', 0, 0, 0]]
main_process()
输出:
main_thread: [['LACE', 1639144800000, 1.157857245, '9:00 December 10, 2021', 'True', 1, 0, 0], ['ARKER', 1639109835404, 0.0, '10:00 December 10, 2021', 'True', 0, 0, 0]]
sub_thread: [['LACE', 1639144800000, 1.157857245, '9:00 December 10, 2021', 'True', 1, 0, 0], ['ARKER', 1639109835404, 0.0, '10:00 December 10, 2021', 'True', 1, 0, 0]]
main_process: [['LACE', 1639144800000, 1.157857245, '9:00 December 10, 2021', 'True', 1, 1, 0], ['ARKER', 1639109835404, 0.0, '10:00 December 10, 2021', 'True', 0, 0, 0]]
sub_process: [['LACE', 1639144800000, 1.157857245, '9:00 December 10, 2021', 'True', 1, 0, 0], ['ARKER', 1639109835404, 0.0, '10:00 December 10, 2021', 'True', 1, 1, 0]]
main_thread: [['LACE', 1639144800000, 1.157857245, '9:00 December 10, 2021', 'True', 2, 1, 0], ['ARKER', 1639109835404, 0.0, '10:00 December 10, 2021', 'True', 0, 0, 0]]
sub_thread: [['LACE', 1639144800000, 1.157857245, '9:00 December 10, 2021', 'True', 1, 0, 0], ['ARKER', 1639109835404, 0.0, '10:00 December 10, 2021', 'True', 2, 1, 0]]
main_process: [['LACE', 1639144800000, 1.157857245, '9:00 December 10, 2021', 'True', 2, 2, 0], ['ARKER', 1639109835404, 0.0, '10:00 December 10, 2021', 'True', 0, 0, 0]]
sub_process: [['LACE', 1639144800000, 1.157857245, '9:00 December 10, 2021', 'True', 1, 0, 0], ['ARKER', 1639109835404, 0.0, '10:00 December 10, 2021', 'True', 2, 2, 0]]
main_thread: [['LACE', 1639144800000, 1.157857245, '9:00 December 10, 2021', 'True', 3, 2, 0], ['ARKER', 1639109835404, 0.0, '10:00 December 10, 2021', 'True', 0, 0, 0]]
sub_thread: [['LACE', 1639144800000, 1.157857245, '9:00 December 10, 2021', 'True', 1, 0, 0], ['ARKER', 1639109835404, 0.0, '10:00 December 10, 2021', 'True', 3, 2, 0]]
main_thread: [['LACE', 1639144800000, 1.157857245, '9:00 December 10, 2021', 'True', 4, 2, 0], ['ARKER', 1639109835404, 0.0, '10:00 December 10, 2021', 'True', 0, 0, 0]]
main_process: [['LACE', 1639144800000, 1.157857245, '9:00 December 10, 2021', 'True', 4, 3, 0], ['ARKER', 1639109835404, 0.0, '10:00 December 10, 2021', 'True', 0, 0, 0]]
sub_process: [['LACE', 1639144800000, 1.157857245, '9:00 December 10, 2021', 'True', 1, 0, 0], ['ARKER', 1639109835404, 0.0, '10:00 December 10, 2021', 'True', 3, 3, 0]]
sub_thread: [['LACE', 1639144800000, 1.157857245, '9:00 December 10, 2021', 'True', 1, 0, 0], ['ARKER', 1639109835404, 0.0, '10:00 December 10, 2021', 'True', 4, 3, 0]]
【问题讨论】:
【参考方案1】:当你这样做时:
l = manager.list()
l = [['LACE', 1639144800000, 1.157857245, '9:00 December 10, 2021', 'True', 0, 0, 0],
['ARKER', 1639109835404, 0.0, '10:00 December 10, 2021', 'True', 0, 0, 0]]
第二个赋值删除第一个赋值并用一个普通的旧 Python 列表替换它。这样做:
l = manager.list(
[['LACE', 1639144800000, 1.157857245, '9:00 December 10, 2021', 'True', 0, 0, 0],
['ARKER', 1639109835404, 0.0, '10:00 December 10, 2021', 'True', 0, 0, 0]]
)
跟进
另一个问题比较棘手。该语句确实将第一个列表转换为托管列表。如果您将线程更改为l.append(7)
,您会看到列表确实增长了。但是,INSIDE 列表仍然是普通的列表对象,它们不是共享的。所以,l
是托管列表,但 l[0]
不是。
你可以通过这样做来解决这个问题
l = manager.list([
manager.list(['LACE', 1639144800000, 1.157857245, '9:00 December 10, 2021', 'True', 0, 0, 0]),
manager.list(['ARKER', 1639109835404, 0.0, '10:00 December 10, 2021', 'True', 0, 0, 0])
])
但如果你这样做,你将不得不以不同的方式打印它们:
print("sub process:", l[0], l[1])
一般来说,像这样共享数据结构并不是一个好主意。你知道实施吗? Manager()
创建另一个新进程,这是一个 TCP 服务器,它接受来自子进程的更新并将更新广播出去。它比使用常规列表慢 100 倍。
没有像这样在进程之间全局共享数据的好方法。只要您了解限制,您可以在共享内存中尝试Array
。线程可以共享一个全局变量,但进程确实需要彼此独立。您可以使用Queue
将结果传回母舰,但像这样更新共享数据结构并不实际。
【讨论】:
我刚试过这个,现在列表根本没有从进程或线程更新。它只是打印与定义相同的嵌套列表。以上是关于进程和线程之间共享和更新列表的主要内容,如果未能解决你的问题,请参考以下文章