使用管道进行 IPC

Posted

技术标签:

【中文标题】使用管道进行 IPC【英文标题】:Using pipe for IPC 【发布时间】:2012-07-18 13:52:57 【问题描述】:

我目前正在学习IPC,我有第一个程序

A:为 B 执行 exec 并等待

B:通过fifo接收来自第三个程序“C”的字符串,并且必须将其重新发送给A

我想在执行之前在 A 中打开一个管道,然后将 fd[1] 作为参数传递给 B

if(pipe(fd)==-1)
    perror("Pipe Failed");
    myExit(EXIT_FAILURE);


close(fd[1]);   
sprintf(fdString,"%d",fd[1]);

    .......

if((int)(pid=fork())>0)

    waiting(status);    

else if(pid==0)    

    close(fd[0]);   

    execl("./B","B",fdString,(char*)0);
    perror("Exec failed");
    myExit(EXIT_FAILURE);


然后在B:

int fd=atoi(argv[1]);

    //Receive string from C 

    len=strlen(string)+1;

if(write(fd,&len,sizeof(int))==-1)
    perror("Error on writing length");
    exit(EXIT_FAILURE); 


if(write(fd,string,len)==-1)
    perror("Error on writing string");
    exit(EXIT_FAILURE);     

我现在的问题是在 A 中读取此字符串。我正在考虑将 SIGUSR1 发送到 A,只要该字符串由 B 在管道上写入并且在 A 中具有类似的内容:

signal(SIGUSR1, signalHandler);
    ........
    static void signalHandler(int signo)
    switch(signo)
    case SIGUSR1:
        listen();
        break;
    default: break;

    

    ........
static void listen()

    int len;

    if(read(fd[0],&len,sizeof(int))<sizeof(int))
        perror("Error reading len");
        myExit(EXIT_FAILURE);   
    

    char string[len];

    if(read(fd[0],&string,len)<len)
        perror("Error reading string");
        myExit(EXIT_FAILURE);   
    
    printf("String: %s with length %d\n", string, len);

但是我得到的是 "Error reading len: Success" ,怎么了?

对不起,如果我的英语不好,感谢任何帮助,谢谢!

【问题讨论】:

【参考方案1】:

写入字符串的程序很可能是segfaulting,因为这行:

if(write(fd,&string,len)==-1)  /* ... */

你应该通过string 没有 &amp;

另一方面,您的错误消息信息量不大,因为 read() 可能返回 0 或小于 sizeof(int) 字节。它只会在返回值为-1 时设置errnoread() 返回 0 或小于预期的事实通常意味着 文件结束 条件,即另一端已关闭管道。

您应该在尝试进一步挖掘之前解决这些问题。

【讨论】:

糟糕,&string 是一个错字,但是我没有 close 在另一边【参考方案2】:

我自己回答,因为我实际上已经解决了自己的问题:

我在 fork() 之前关闭了 fd[1],这将导致 fd[1] 的孩子关闭(在读取时出错!)正如乙醇 (C2H5OH ;)) 所说。

我接受他的回答,因为它让我找到了解决方案!

【讨论】:

没错,我完全错过了close(fd[1])这一行,它确实在分叉之前关闭了管道的写端。

以上是关于使用管道进行 IPC的主要内容,如果未能解决你的问题,请参考以下文章

go语言快速入门 IPC之管道通信 8

命名管道与 IPC 的 COM

当 2 个进程尝试同时在不同管道上相互通信时,使用命名管道的 WCF IPC 会崩溃

dotnet 替换 ASP.NET Core 的底层通讯为命名管道的 IPC 库

IPC使用管道?

LINUX FIFO 命名管道 (IPC) 在特定文件描述符处停止写入/读取消息