#at initialization
partial_results_lock = threading.Lock()
partial_results_left=<number of threads>
# in the thread, if the queue is empty
with partial_results_lock:
queue.push(state)
state=1
partial_results_left-=1
if partial_result_left!=0: return # after we start over and push
#the final result, the counter will become -1
<start over>
我真的很喜欢the idea presented in the other answer。在
当阶乘是数[1,n]的computed as the product时:
您可以使用切片生成要由工人处理的数字。例如:
^{pr2}$Map这是一个process pool,然后减少这些产品的结果得到你的最终解决方案。在
不要使用threading模块来实现这一点。这是一个占用CPU的任务,它将被Global Interpreter Lock阻止。multiprocessing模块使用进程而不是线程来绕过这一步。在
阶乘就是一系列数字的相乘。因为乘法是associative,所以可以按任何顺序乘法。更具体地说,可以将序列分成任意数量的部分,独立地将这些部分相乘,然后组合结果。在
由于CPython的GIL,您可能一次只运行一个线程,但任务的本质可能是简单地练习线程同步。在
^{} 和^{} 看起来是适合这份工作的工具。我将给出两个可能实现的示例:
Queue
和多个Thread
对象,每个对象都将另一个更有趣的实现是:
Queue
创建多个线程,每个线程将
Queue
中取一个数字,如果可以的话(即不阻塞)这里有趣的部分是如何在队列为空后继续操作:
Queue
并退出,让主线程在所有线程退出后进行最后的乘法相反,线程可能会将结果推回到队列并退出。但是,您需要以某种方式确保在获得最终结果(并将其推入队列)之前并不是所有线程都退出。在
一种方法是在联锁计数器中跟踪有多少部分结果被推送到队列中,并防止线程在检测到要处理最后一个结果时退出:
在多线程应用程序中,最好最小化不同线程之间存在的数据依赖关系。在
在您提到的阶乘递归解决方案中,很难找到不依赖于其他计算结果的计算。在
一种不同的方法是将阶乘分解成多个部分。 例如,对于两个线程,可以执行以下操作:
n! = [1 * 2 * 3 * .. * (n/2)] * [(n/2 + 1) * ... * n]
第一个线程将计算值:
v1 = 1 * 2 * 3 * .. * (n/2)
第二个线程将计算:
v2 = (n/2 + 1) * ... * n
然后,当两个线程都完成时,主线程将计算
n! = v1 * v2
。在这可以通过将输入阶乘分解为
k
不同的部分(而不是上面的示例中的两个)来推广使用k
线程。在相关问题 更多 >
编程相关推荐