我已经成功地在 Julia 中使用多线程来模拟具有不断变化的值的图,并且希望在 Python 中实现类似的方案。
因为某个节点在时间
t
处的值可能取决于任何其他给定节点在时间 t-1
处的值,因此线程必须在每个时间步结束时达成一致,但可以在一段时间内独立更新元素步骤给出了前一个时间步骤的共享信息。我不确定 Julia 在幕后做了什么,但多线程对于此目的非常有效。我已经实现了一种 hacky 方法来在 Python 中实现相同的功能(如下),但是在每个时间步重复创建和销毁线程要慢得多,并且似乎不允许重用线程。在我深入学习 Python 多线程的本质之前,也许有人可以就该课程的可行性提出建议。使用 Python 的多处理(或其他库)以这种方式并行化图形更新是否有意义?
import multiprocessing
T = 1000
for t in range(T):
thrds = []
for n,node in enumerate(net.nodes):
thrds.append(
multiprocessing.Process(
target=update_node,
args=(n,node,t)
)
)
for thrd in thrds:
thrd.start()
for thrd in thrds:
thrd.join()
del(thrds)
因为时间 t 时节点的值可能取决于时间 t-1 时任何其他给定节点的值,所以线程必须在每个时间步结束时达成一致
multiprocessing.Barrier
对象来保持所有线程彼此同步。
您在构造
N
对象时指定多个线程Barrier
,然后线程可以调用barrier.wait()
。第一个 N-1
调用者将被阻塞,直到第 N
个线程调用 wait()
。然后,所有 wait()
调用返回,屏障自动重置,准备再次使用。
尝试运行这个来看看我的意思:
#!/usr/bin/env python3
import multiprocessing as mp
import time
NWORKERS=3
NTHREADS=NWORKERS+1 # main thread + worker threads
NGENERATIONS=3
def work_fun(barrier, tag):
for generation in range(NGENERATIONS):
barrier.wait()
print(f"I am worker{tag}, generation={generation}", flush=True)
if __name__ == "__main__":
ctx = mp.get_context('spawn')
barrier = ctx.Barrier(NTHREADS)
procs = []
for i in range(NWORKERS):
proc = ctx.Process(target=work_fun, args=(barrier, i))
proc.start()
procs.append(proc)
for i in range(NGENERATIONS):
time.sleep(1)
barrier.wait()
for i in range(NWORKERS):
procs[i].join()
print("Nighty Night!")