程序在使用进程时挂起

时间:2016-10-10 12:55:35

标签: python c fork

我试图将我的c代码传递给我的python代码。 我在我的c代码中创建了一个名称管道,将其发送到python并将其打印出来。我想做同样的事情,我在python中创建命名管道并且c读取它,但是我的程序似乎停止(我想同时执行这两个),因此我使用进程。

我的代码:

int main(void) {
    int pid;
    FILE * fp;
    char *calledPython="./a.py"; 
    char *pythonArgs[]={"python",calledPython,"a","b","c",NULL};
    FILE * fp2;
    char str[40];
    pid = fork();

    if(pid == 0) {
        mkfifo("./test",0666);
        fp = fopen("./test","w");
        fprintf(fp,"Hello\n");
        fprintf(fp,"World\n");
    }
    else {
        execvp("python",pythonArgs);
        // if we get here it misfired
        perror("Python execution");
        kill(pid,SIGKILL);
    }

    fp2 = fopen("./test2","r");
    if(fp2 == NULL) {
        printf("NUll\n");
    }

    else {
        fscanf(fp2, "%s", str);
        printf("received from test2 %s\n", str);
   }
   fclose(fp);
    return 0;
}

我的python代码:

#!/usr/bin/python


import os, sys

with open("./test") as fp:
    for line in fp:
        print line


path = "./test2"
os.mkfifo(path)

fifo = open(path,"w")
fifo.write("Message from the sender\n")
fifo.close()

其中./test是初始命名管道,python读入,而./test2是第二个命名管道c是要读入的。 但是,一旦我在python中写入第二个管道,我的程序就会挂起:

path = "./test2"
os.mkfifo(path)

fifo = open(path,"w")
fifo.write("Message from the sender\n")
fifo.close()

我从终端获得的输出是:

NUll
Hello

World

如果我再次运行它,我只是得到一个空行(根本没有打印)。 我试图在父进程中打开第二个命名管道,但似乎没有太大变化。我不知道我在哪里出错了,有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我目前没有手头的unix盒子进行测试。但可能的问题是你不能在父进程中关闭fifo。

每当你有一个像for line in file这样的循环时,该循环将一直持续到文件结束。与普通文件不同,fifo不会"结束"直到写作结束的过程关闭fifo。如果你不关闭fifo,阅读过程将在阅读中阻止,并且无法继续进行。

我的代码可能存在其他问题,我不知道。

其他一些说明:

  • 你应该在execvp之前使用mkfifo,目前你正在并行执行它们并希望mkfifo在python程序尝试打开文件之前完成。可能,但不确定。

  • 在第二个fifo上还有另一个竞争条件,我认为这个竞争条件不太可能按预期工作。

  • 您永远不会删除命名管道,下次它会尝试创建一个已经存在但无效的文件。

  • SIGKILL很少使用正确的信号。我建议你阅读SIGKILL,SIGTERM等之间的区别。

  • 像mkfifo这样的系统调用可能会失败,建议检查错误的返回值。