2016-10-10 113 views
1

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

我的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是最初的命名管道,蟒蛇在读取和./test2是第二个命名管道c是。soposed在读 然而,我的程序挂起,一旦我写信给我的第二个管道在Python:

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

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

我从终端得到的输出是:

NUll 
Hello 

World 

,如果我再次运行它,我只是得到一个空行(不打印在所有)。 我试图在父进程中打开第二个命名管道,这似乎没有太大的改变。我不确定我在这里出了什么问题,有什么想法?

+0

这看起来像是充满了竞争条件。 – melpomene

回答

0

我手头没有unix box来测试。但是可能的问题是,你不关闭父进程中的fifo。

只要你有一个像for line in file这样的循环,该循环将一直持续到文件结束。与普通文件不同,在写入结束进程关闭fifo之前,fifo不会“结束”。如果您没有关闭FIFO,读取过程将在读取调用中阻塞,并且无法进行。

您的代码可能存在其他问题,我错过了。

其他一些注意事项:

  • 你应该mkfifo你execvp之前,您目前正在做他们并行,并希望你的Python程序试图打开该文件之前mkfifo完成。可能,但不确定。

  • 第二个fifo还有另外一个竞赛条件,我认为这个竞争条件不太可能像预期的那样工作。

  • 你永远不会删除命名管道,下次它会尝试创建一个已经存在的文件不起作用。

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

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