我的代码草图如下:
def func1(c):
return a,b
def func2(c,x):
if condition:
a,b = func1(c)
x.append(a,b)
func2(a,x)
func2(b,x)
return x
x = []
y = func2(c, x)
正如您可能从代码中发现的那样,问题是我希望func2(b)
只要条件为真,即在func2(a)
被替换之前与b
并行计算来自a
的{{1}}新b
。但根据我的算法,由于新的b,这显然不可能发生。
我认为这样的问题对于并行计算方法可能是完美的。但是,我之前没有使用它,而我对此的了解非常有限。不过,我确实试过了How to do parallel programming in Python的建议。但是我得到的结果与上面的草图相同。
答案 0 :(得分:0)
警告:线程可能不够平行(请参阅Global Interpreter Lock
上的https://docs.python.org/2/library/threading.html注释),因此您可能需要使用multiprocessing
库(https://docs.python.org/2/library/multiprocessing.html)
...所以我欺骗了/懒惰&使用线程/流程中性术语“工作”。您需要为我使用“作业”的所有地方选择线程或多处理。
def func1(c):
return a,b
def func2(c,x):
if condition:
a,b = func1(c)
x.append(a,b)
a_job = None
if (number_active_jobs() >= NUM_CPUS):
# do a and b sequentially
func2(a, x)
else:
a_job = fork_job(func2, a, x)
func2(b,x)
if a_job is not None:
join(a_job)
x = []
func2(c, x)
# all results are now in x (don't need y)
...如果你出于某种原因需要a,b对一起完成,那将是最好的。
如果你愿意让调度程序变得疯狂,那么你就可以“完成”他们的所有工作。最后是join
:
def func1(c):
return a,b
def func2(c,x):
if condition:
a,b = func1(c)
x.append(a,b)
if (number_active_jobs() >= NUM_CPUS):
# do a and b sequentially
func2(a, x)
else:
all_jobs.append(fork_job(func2, a, x))
# TODO: the same job-or-sequential for func2(b,x)
all_jobs = []
x = []
func2(c, x)
for j in all_jobs:
join(j)
# all results are now in x (don't need y)
NUM_CPUS检查可以使用threading.activeCount()
而不是完整的工作人员威胁池(python - how to get the numebr of active threads started by specific class?)来完成。
但是通过多重处理,您需要处理更多与JoinableQueue
和固定大小Pool
工作人员有关的工作
答案 1 :(得分:0)
根据你的解释,我感觉不是b
得到更新(这不是,正如DouglasDD所解释的那样),而是x
。要让两个递归调用都在同一个x
上运行,您需要采用x
的某种快照。最简单的方法是沿
def func2(c, x, length):
...
x.append(a, b)
func2(a, x, length + 1)
func2(b, x, length + 1)