我不确定我想做的是有效的做法,但是在这里行得通:
我需要高度并行化我的程序,因此我认为我可以进行2-3个进程,每个进程可以具有2-3个线程。
1)这可能吗?
2)有什么要点吗?
3)这是我的代码,但是当我尝试加入进程时,它挂起了。
PQ = multiprocessing.Queue()
[...]
def node(self, files, PQ):
l1, l2 = self.splitList(files)
p1 = multiprocessing.Process(target=self.filePro, args=(l1,PQ,))
p2 = multiprocessing.Process(target=self.filePro, args=(l2,PQ,))
p1.daemon = True
p2.daemon = True
p1.start()
p2.start()
p1.join() # HANGS HERE
p2.join()
while 1:
if PQ.empty():
break
else:
print(PQ.get())
PQ.join()
def filePro(self,lst,PQ):
TQ = queue.Queue()
l1, l2 = self.splitList(lst)
t1 = threading.Thread(target=self.fileThr, args=('a',l1,TQ,))
t2 = threading.Thread(target=self.fileThr, args=('b',l2,TQ,))
t1.daemon = True
t2.daemon = True
t1.start()
t2.start()
t1.join()
t2.join()
while 1:
if TQ.empty():
break
else:
PQ.put(TQ.get())
TQ.task_done()
TQ.join()
def fileThr(self,id,lst,TQ):
while lst:
tmp_path = lst.pop()
if (not tmp_path[1]):
continue
for item in tmp_path[1]:
TQ.put(1)
TQ.join()
最佳答案
是的。
是的。但通常不是您要寻找的重点。
首先,几乎每个现代操作系统都使用“固定”调度程序。散布在3个程序中的8个线程或散布在8个程序中的8个线程之间没有区别。*
*在某些您仅知道与同一程序中的线程共享的地方,通过谨慎地使用进程内锁或其他同步原语,某些程序可以显着受益,当然,通过避免在这些地方共享内存,但是您将无法通过在线程之间平均分配工作,并在进程之间平均分配线程来获得 yield 。
其次,即使您在默认的CPython解释器中使用了旧的SunOS,全局解释器锁(GIL)也会确保一次只能有一个线程在运行Python代码。如果您花时间从显式释放GIL的C扩展库中运行代码(例如某些NumPy函数),线程可以提供帮助,但是否则,它们无论如何都最终会序列化。
线程和进程一起使用的主要情况是同时进行CPU绑定(bind)和I/O绑定(bind)。在这种情况下,通常一个人正在喂养另一个人。如果I/O供给CPU,请在主进程中使用单个线程池来处理I/O,然后使用辅助进程池来使CPU对结果进行处理。如果不是这样,请使用工作进程池来执行CPU工作,然后让每个工作进程使用线程池来执行I/O。
如果不提供minimal, complete, verifiable example,则很难调试代码。
但是,我可以看到一个明显的问题。
您正在尝试将TQ
用作生产者-消费者队列,将t1
和t2
用作生产者,并将filePro
父级用作消费者。您的使用者直到TQ.task_done()
和t1.join()
返回之后才调用t2.join()
,直到这些线程完成后才发生。但是这些生产者不会完成,因为他们在等您调用TQ.task_done()
。因此,您陷入了僵局。
而且,由于每个子进程的主线程都处于死锁状态,因此它们永远都不会结束,因此p1.join()
将永远阻塞。
如果您确实希望主线程在完成其他工作之前一直等到其他线程完成,则不需要生产者-消费者习惯用语。只是让 children 做他们的工作并退出而无需调用TQ.join()
,而不必理会 parent 中的TQ.task_done()
。 (请注意,您已经使用PQ
正确执行了此操作。)
另一方面,如果您希望它们并行工作,则在完成循环之前,请不要尝试对子线程进行join
。
关于python - Python多处理与多线程结合,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27455155/