从Python线程生成的子进程的输出为什么会延迟?

2024-09-26 18:07:47 发布

您现在位置:Python中文网/ 问答频道 /正文

这是我昨天发帖的扩展,现在还没有解决:Why does my Python thread with subprocess not work as expected?

与此同时,我发现了一些有趣的细节,所以我决定创建一个新的帖子。关键是:当从线程中生成子进程时,会出现一些问题。在

平台:Windows 7 Enterprise,Python 3.6.1

在下面的代码中,我希望运行一个C-executable并将其输出到stdout的字符串中。出于测试目的,可执行文件接受两个参数:延迟和文件名(此处不使用)。程序将Sleep now写入stdout,休眠给定毫秒数,最后写入after sleep和{}。在

这是可执行文件的C源代码:

int main(int argc, char *argv[])
{
    int sleep = 0;
    FILE * outfile = NULL;

    if (argc > 1)
    {
        sleep = atoi(argv[1]);
    }

    if (argc > 2)
    {
        outfile = fopen(argv[2], "w");
    }

    printf("Sleep now...\n");

    Sleep(sleep);

    if (outfile) fprintf(outfile, "output-1");
    printf("after sleep\n");
    printf("END\n");

    if (outfile) fclose(outfile);
    fclose(stdout);
    exit (0);
}

这是Python代码:

^{pr2}$

这些作业的延迟分别为4秒、8秒和1秒。在

worker_nok调用proc.communicate()-这是我最初的方法,但它不起作用:当运行这两个作业时,我得到以下输出:

w4sec.nok: b'Sleep now...\r\nafter sleep\r\nEND\r\n'
w8sec.nok: b'Sleep now...\r\nafter sleep\r\nEND\r\n'

8秒后收到全部信号。相反,我希望

... 4 sec ...
w4sec.nok: b'Sleep now...\r\nafter sleep\r\nEND\r\n'

... 4 sec ...
w8sec.nok: b'Sleep now...\r\nafter sleep\r\nEND\r\n'

虽然4秒的过程肯定已经完成,但它的输出只有在第二个作业也完成之后才可用。在

这是我上次发帖时的状态。在

为了找出错误,我试图通过直接读取stdout来替换{},这是在{}函数中实现的。当read返回空字符串时,将标识EOF条件。打电话时,我得到:

... 4 seconds ...

w4sec.txt: b'Sleep now...\r\n'
w4sec.txt: b'after sleep\r\n'
w4sec.txt: b'END\r\n'

... 4 seconds ...

w8sec.txt: b'Sleep now...\r\n'
w8sec.txt: b'after sleep\r\n'
w8sec.txt: b'END\r\n'
w8sec.txt: got EOF
w8sec.txt: END
w4sec.txt: got EOF
w4sec.txt: END

但是我希望:

w4sec.txt: b'Sleep now...\r\n'
w8sec.txt: b'Sleep now...\r\n'

... 4 seconds ...

w4sec.txt: b'after sleep\r\n'
w4sec.txt: b'END\r\n'
w4sec.txt: got EOF
w4sec.txt: END

... 4 seconds ...   

w8sec.txt: b'after sleep\r\n'
w8sec.txt: b'END\r\n'
w8sec.txt: got EOF
w8sec.txt: END

大问题是:

1)为什么在我得到sleep now之前会有延迟?可执行文件使此输出立即可用。stdout是否只有在进程终止后才可用?在

2)更重要的是:为什么4秒的EOF只有在8秒的调用完成后才可用?在

我希望这个输入可以清楚地说明为什么原始版本显示了观察到的行为:stdout处于EOF状态太晚了,并且留下了communicate()的调用阻塞!在

我很感激你的意见,因为我已经为此工作了12个多小时了。。。在


Tags: txtifstdoutsleepnowoutfileendafter

热门问题