Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python多处理子进程在运行退出时挂起_Python_Multiprocessing - Fatal编程技术网

Python多处理子进程在运行退出时挂起

Python多处理子进程在运行退出时挂起,python,multiprocessing,Python,Multiprocessing,我正在使用多处理调试一个问题。 我有以下孩子: class Target(multiprocessing.Process): def __init__(self, work_queue, result_queue, suite_name, test_settings, html_log_dir, output_file, ip_address, fit_dir): multiprocessing.Process.__init__(self) # init

我正在使用多处理调试一个问题。
我有以下孩子:

class Target(multiprocessing.Process):
    def __init__(self, work_queue, result_queue, suite_name, test_settings, html_log_dir, output_file, ip_address, fit_dir):
        multiprocessing.Process.__init__(self)

        # initialize other variables

    def run(self):
        print multiprocessing.current_process()
        suite_start_time = time.clock()
        while not self.kill_received:
            # get a task
            try:
                job = self.work_queue.get(True, 2)
            except Queue.Empty:
                self._log('Work queue empty, creating XML result file')
                self.create_xml_result_file(suite_start_time)
                break

            # the actual processing, run the test.

        fitnesse_common.log_output("\n(PID " + str(self.pid) + "): End of process")

    def create_xml_result_file(self, start_time):
        # generate result 
父进程基本上只启动几个(12)目标,并等待它们全部加入

问题是,由于某种原因,子进程正在运行到run函数的末尾(我看到了进程末尾打印),然后由于某种原因没有终止,这会阻止父进程继续

编辑-并非所有生成的进程都挂起,只有几个挂起。在生成的12个进程中,通常只有2-4个进程在完成运行功能后挂起

我考虑在run函数结束时调用terminate,但Python文档表明这是一个坏主意

我已经看了几篇关于Python multprocessing的堆栈溢出的不同文章,其中大多数都与父进程的问题有关

任何想法或帮助都将不胜感激

更新:下面是一个脚本,可以很容易地重现问题:

import multiprocessing, Queue
import subprocess
import time
import sys

class Target(multiprocessing.Process):
    def __init__(self, work_queue, results_queue, delay_length):
        # base class initialization
        multiprocessing.Process.__init__(self)

        # job management stuff
        self.work_queue = work_queue
        self.results_queue = results_queue
        self.delay_length = delay_length
        self.kill_received = False

    def run(self):
        while not self.kill_received:
            # get a task
            try:
                job = self.work_queue.get(True, 2)
            except Queue.Empty:
                self._log('Work queue empty, prepare to terminate')
                break

            time.sleep(self.delay_length)
            self._log("Sleeping done")

            results = self._run_an_application(job)

            self.results_queue.put(results)
            self._log("Have put results on queue " + str(job) + "-" + results)
        self._log("\n(PID " + str(self.pid) + "): End of process")
    def _log(self, text):
        print ('PID ' + str(self.pid) + ' => ' + text)
        sys.stdout.flush()

    def _run_an_application(self, app):
        try: 
            test_output = subprocess.check_output(app)
        except subprocess.CalledProcessError, e:
            log_output('### Process check_output threw exception CalledProcessError')
            test_output = e.output

        return test_output

if __name__ == "__main__":

    test_jobs = []
    started_targets = []

    # run
    # load up work queue
    for i in range(500):
        test_jobs.append('spewage')
    work_queue = multiprocessing.Queue()

    for job in test_jobs:
        work_queue.put(job)

    # create a queue to pass to targets to store the results
    result_queue = multiprocessing.Queue()

    # spawn targets
    for i in range(12):
        started_targets.append(Target(work_queue, result_queue, i))

    # start all targets
    for i in range(len(started_targets)):
        started_targets[i].start()
        print "starting process no %s with id: %s" % (i, started_targets[i].pid)

    print 'Waiting for all processes to join'

    # wait for all targets to finish
    for i in range(len(started_targets)):
        started_targets[i].join()

    print 'All processes have joined'

    # collect the results off the queue
    while not result_queue.empty():
        target_result = result_queue.get()
        print "Test job - " + target_result
    print ('All Tests completed')
这是“spewage”应用程序的源代码(它是C++)

#include <iostream>
#include <windows.h>
using namespace std;

int main()
{
    for (int i = 0; i < 500; i++)
    {
        cout << "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" << endl;
        Sleep(20); 
    }
    return 0;
}
#包括
#包括
使用名称空间std;
int main()
{
对于(int i=0;i<500;i++)
{

cout我设法解决了这个问题。它似乎与子进程中的输出量有关。在进程的run()函数结束时,我需要将self.results\u queue.cancel\u join\u thread()放入


我仍然很好奇为什么它在没有太多标准输出的情况下工作,但在有标准输出的情况下进程会挂起。根据Python文档,我使用结果队列的方式应该一直锁定,即使它没有锁定。

这肯定不是解决当前问题的方法,但是您必须使用我支持的子进程吗在您当前的设计中?或者您可以改为使用线程吗?这是我继承的代码,我个人不知道他们为什么选择使用进程。进程运行FitNesse测试运行程序,并创建一个我们解析的结果文件。但我个人不认为有任何理由不能在线程中完成(这可能是我做这件事的方式,而不是创建怪物进程树)。如果是这样的话,也许值得尝试将基类multiprocessing.Process更改为threading.Thread。API在很大程度上应该匹配,这取决于您的进程对象有多复杂。请确保:你们都知道CPython的全局解释器锁(GIL)它对多线程代码的影响如何?这是使用进程而不是线程的最可能原因。是否有可能一些子进程正在等待将某些内容放入结果队列,而父进程不会因为等待子进程结束而清空该结果队列?能否提供一个可运行的示例来演示此问题,以便读者我们能够复制它