尝试在主进程-主线程之间共享和更新列表;子进程-子线程。目前看来,主进程和主线程都共享列表的一个副本的更新,子进程和子线程共享列表的另一个副本。我本以为经理会允许所有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]]
执行此操作时:
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
将结果传输回母船,但像这样更新共享数据结构并不实际。