使用管道进行 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
没有 &
。
另一方面,您的错误消息信息量不大,因为 read()
可能返回 0 或小于 sizeof(int)
字节。它只会在返回值为-1
时设置errno
。 read()
返回 0 或小于预期的事实通常意味着 文件结束 条件,即另一端已关闭管道。
您应该在尝试进一步挖掘之前解决这些问题。
【讨论】:
糟糕,&string 是一个错字,但是我没有 close 在另一边【参考方案2】:我自己回答,因为我实际上已经解决了自己的问题:
我在 fork() 之前关闭了 fd[1],这将导致 fd[1] 的孩子关闭(在读取时出错!)正如乙醇 (C2H5OH ;)) 所说。
我接受他的回答,因为它让我找到了解决方案!
【讨论】:
没错,我完全错过了close(fd[1])
这一行,它确实在分叉之前关闭了管道的写端。以上是关于使用管道进行 IPC的主要内容,如果未能解决你的问题,请参考以下文章
当 2 个进程尝试同时在不同管道上相互通信时,使用命名管道的 WCF IPC 会崩溃