当前位置: 技术问答>linux和unix
一个进程间通信问题
来源: 互联网 发布时间:2017-01-25
本文导语: 问题起源: A程序 启动一个进程B来运行ping命令(假设), 现在我想把B中ping命令的输出, 返还给A程序. 解决1: A 启动B进程运行ping 命令的代码 改为: ping 192.168.1.1 > ping_output.file 问题: 这样的话, A程序...
问题起源: A程序 启动一个进程B来运行ping命令(假设), 现在我想把B中ping命令的输出, 返还给A程序.
解决1: A 启动B进程运行ping 命令的代码 改为: ping 192.168.1.1 > ping_output.file
问题: 这样的话, A程序 就得去那个 ping_output.file 里面取输出, 这里最主要问题是 怎么用上面这条命令启动程序, 事实证明用 exec函数来执行 会失败, 因为中间有 ">"重定向, 没有Shell来解析;
最后想了个丑办法 , 将命令写到"ping.sh"里面 再execlp("sh","ping.sh") 这样来运行, 后果就是多开了个sh进程,更不好控制
解决2: 改ping 源码, 将所有输出 dup2(fd, STDOUT_FILENO); fd = open(ping_output.file, O_RDWR); 这样直接将ping所有输出 重定向到 fd (即文件ping_output.file)中
虽然问题好像是解决了, 但是让人蛋疼的是, 往往程序(输出比ping多得多)结束了, 数据还没读完, 结果A程序判断 B程序已经执行完成, 立马结束, 导致数据不完整.
解决3: 突然间想到用管道, 直接通信, 而不老是围着共享文本文件来通信 . 代码如下, 耐心看的朋友应该可以看出问题来
如果有耐心朋友看完了的, 非常感谢~~~!! 知道我有多么可怜了吧! 弄了一天了~ 蛋疼!
解决1: A 启动B进程运行ping 命令的代码 改为: ping 192.168.1.1 > ping_output.file
问题: 这样的话, A程序 就得去那个 ping_output.file 里面取输出, 这里最主要问题是 怎么用上面这条命令启动程序, 事实证明用 exec函数来执行 会失败, 因为中间有 ">"重定向, 没有Shell来解析;
最后想了个丑办法 , 将命令写到"ping.sh"里面 再execlp("sh","ping.sh") 这样来运行, 后果就是多开了个sh进程,更不好控制
解决2: 改ping 源码, 将所有输出 dup2(fd, STDOUT_FILENO); fd = open(ping_output.file, O_RDWR); 这样直接将ping所有输出 重定向到 fd (即文件ping_output.file)中
虽然问题好像是解决了, 但是让人蛋疼的是, 往往程序(输出比ping多得多)结束了, 数据还没读完, 结果A程序判断 B程序已经执行完成, 立马结束, 导致数据不完整.
解决3: 突然间想到用管道, 直接通信, 而不老是围着共享文本文件来通信 . 代码如下, 耐心看的朋友应该可以看出问题来
// B程序 使用pipe ,测试程序
#include
#include
#include
#include
#include
#include
static int flag = 0;
int main()
{
char output[128] = {0};
int fd[2];
int pid;
int *status;
pipe(fd);
/*为了让下面的READ不阻塞 并判断waitpid*/
int flag = fcntl(fd[0], F_GETFL, 0);
flag |= O_NONBLOCK;
if(fcntl(fd[0], F_SETFL, flag) 0)
{//父进程可以waitpid来等待子进程结束, 所以把读放在父进程里, ping 命令程序放在子进程里
while(1)
{
while(read(fd[0], output, 128) == 128)
if(strlen(output) != 0)
{//这里为了调试 不出现满屏的"parent Process output : "
printf("parent Process output : %sn", output); //这里调试是输出来,如果是我的程序里,就是把output发送给程序A
memset(output,0, sizeof(output));
}
if(waitpid(pid, status, WNOHANG) == pid)
//if(WIFEXITED(status) !=0 || WIFSIGNALED(status))
{//如果不阻塞方式 等待子进程退出成功, 就退出
printf("----fir = %d -- sec = %d----n",WIFEXITED(status), WIFSIGNALED(status));
printf("Process parent exitn");
exit(0);
}
}
}
else
{
//将ping 命令所有输出重定向到 写管道
dup2(fd[1], STDOUT_FILENO);
dup2(fd[1], STDERR_FILENO);
printf("Oh my buf where...n");
printf("Oh my buf where...n");
// **** 省略无数个printf...
sleep(5); //问题1: 不管怎么弄, 反正都是等待5秒后 父进程才能读到数据. WHY? 还有优先顺序?
//问题2: 父进程, 根本不按顺序输出, 那A进程怎么接收咯, SHIT
}
return 0;
}
如果有耐心朋友看完了的, 非常感谢~~~!! 知道我有多么可怜了吧! 弄了一天了~ 蛋疼!
|
还有,一个popen就解决这个问题了,而且用管道做也是popen的实现,APUE都是源代码.
#include
#include
#include
#include
#include
/* no error check at all */
int main(int argc, char* argv[])
{
int m_pipe[2];
pid_t pid;
pipe(m_pipe);
if ((pid = fork()) > 0) //parent
{
char ping_out[100];
int nbytes = 0;
close(m_pipe[1]);
while ((nbytes = read(m_pipe[0], ping_out, 100)) != 0)
{
write(STDOUT_FILENO, ping_out, nbytes);
}
close(m_pipe[0]);
wait(NULL);
}
else if (pid == 0) //child
{
dup2(m_pipe[1], STDOUT_FILENO);
dup2(m_pipe[1], STDERR_FILENO);
close(m_pipe[0]);
char command[100];
sprintf(command, "ping -c 4 %s", argv[1]);
execl("/bin/bash", "sh", "-c", command, NULL);
exit(127); //execl error , or never reach here
}
else
{
fprintf(stderr, "fork errorn");
exit(1);
}
return 0;
}
您可能感兴趣的文章:
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。