fork和pipe,一个父进程和多个子进程的通信问题

LixueDaddy 2012-06-16 03:17:24
各位大牛好啊,最近在学习进程控制,现在用到了fork和pipe,一个父进程和多个子进程的通信问题。
是多个子进程将数据发送到父进程,父进程判断后决定关闭某个子进程。现在遇到的问题是,我的父进程读取的信息都是第一个子进程的内容,其他的子进程的内容被忽略了。
怎样解决这个问题?
还有,当父进程想给某几个特定的子进程发送消息,是怎样具体实现的,谢谢啦。
# include <unistd.h>
# include <time.h>
# include <stdlib.h>
# include <stdio.h>
# include <string.h>



int main(int argc, char *argv[])
{
int iSecret, count;
int pCount= atoi(argv[1]);
pid_t* pid[pCount];
int mtspipe[2], stmpipe[2];
char buf[200], len;


// Create the pipe: master to slave, slave to master.
//If succeed return 0, else -1;
if(pipe(mtspipe))
{
fprintf(stderr,"Create master to slave pipe failed.\n");
return EXIT_FAILURE;
}

if(pipe(stmpipe))
{
fprintf(stderr,"Create slave to master pipe failed.\n");
return EXIT_FAILURE;
}

//Create the child process
if(argc>1)
{
for(count=0;count<pCount;count++)
{

pid[count] = fork();
if(pid[count]==0) //child process
{
close(mtspipe[1]); //close write of mtspipe
close(stmpipe[0]); //close read of stmpipe
//char str[65];

srand(time(NULL));
iSecret = rand()%6+1;
sprintf(buf,"%d:%d",getpid(),iSecret);
write(stmpipe[1],buf,strlen(buf));

printf("This is what we send to master:%s\n",buf);

return EXIT_SUCCESS;
}

else if(pid[count] == -1)
{
printf("Error\n");
}
else // master process
{

close(mtspipe[0]); //close read of mtspipe
close(stmpipe[1]); //close write of stmpipe
len=read(stmpipe[0],buf,sizeof(buf)); //read from stmpipe
printf("This is what we read from slave:%s\n",buf);
sleep(1);
}
}

//wait for all the sub-process to terminate
int i = 0;
for (; i < pCount; ++i) {
int status;
while (-1 == waitpid(pid[i], &status, 0));
if (WIFEXITED(status))
printf("Child exited with code %d\n", WEXITSTATUS(status));
else if (WIFSIGNALED(status))
printf("Child terminated abnormally, signal %d\n", WTERMSIG(status));
}


}
else
{
printf("The command has no other arguments\n");
}
return 0;
}
...全文
1035 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
weiguozhe 2012-06-19
  • 打赏
  • 举报
回复

# include <unistd.h>
# include <time.h>
# include <stdlib.h>
# include <stdio.h>
# include <string.h>



int main(int argc, char *argv[])
{
int iSecret, count;
int pCount= atoi(argv[1]);
//pid_t *pid[pCount];
pid_t pid[pCount];
int mtspipe[2], stmpipe[2];
char buf[200], len;


// Create the pipe: master to slave, slave to master.
//If succeed return 0, else -1;
/*if(pipe(mtspipe))
{
fprintf(stderr,"Create master to slave pipe failed.\n");
return EXIT_FAILURE;
}*/

if(pipe(stmpipe))
{
fprintf(stderr,"Create slave to master pipe failed.\n");
return EXIT_FAILURE;
}

//Create the child process
if(argc>1)
{
for(count=0;count<pCount;count++)
{

pid[count] = fork();
if(pid[count]==0) //child process
{
//close(mtspipe[1]); //close write of mtspipe
//close(stmpipe[0]); //close read of stmpipe
//char str[65];

srand(time(NULL));
iSecret = rand()%6+1;
sprintf(buf,"%d:%d",getpid(),iSecret);
write(stmpipe[1],buf,strlen(buf));

printf("This is what we send to master:%s\n",buf);

return EXIT_SUCCESS;
}

else if(pid[count] == -1)
{
printf("Error\n");
}
else // master process
{

//close(mtspipe[0]); //close read of mtspipe
//close(stmpipe[1]); //close write of stmpipe
len=read(stmpipe[0],buf,sizeof(buf)); //read from stmpipe
printf("This is what we read from slave:%s\n",buf);
sleep(1);
}
}

//wait for all the sub-process to terminate
int i = 0;
for (; i < pCount; ++i)
{
int status;
//while (-1 == waitpid(pid[i], &status, 0));
waitpid(pid[i], &status, 0);
if (WIFEXITED(status))
printf("Child exited with code %d\n", WEXITSTATUS(status));
else if (WIFSIGNALED(status))
printf("Child terminated abnormally, signal %d\n", WTERMSIG(status));
}


}
else
{
printf("The command has no other arguments\n");
}
return 0;
}
qq120848369 2012-06-17
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

我为每个子程序都创建了管道来与父进程交换信息,这样会不会造成资源浪费,两对管道是否可以完成这个任务?前者可以解决之前遇到的只读取第一个子程序的问题。引用 1 楼 的回复:

close(mtspipe[0]); //close read of mtspipe
close(stmpipe[1]); //close write of stmpipe

这两个你父进程关了多少次了,而且……
[/Quote]

写入量小于PIPE_SIZE可以原子写入,否则你就得掂量掂量了,注意字节流拆包问题。

另外,能不能别把计算机想的和傻逼一样,有几个人能遇到所谓的性能瓶颈。

LixueDaddy 2012-06-17
  • 打赏
  • 举报
回复
的确,我还需要分析一下EINTR造成的影响。谢谢啦。[Quote=引用 2 楼 的回复:]

for (; i < pCount; ++i) {
int status;
while (-1 == waitpid(pid[i], &status, 0));
if (WIFEXITED(status))
printf("Child exited with code %d\n", W……
[/Quote]
LixueDaddy 2012-06-17
  • 打赏
  • 举报
回复
我为每个子程序都创建了管道来与父进程交换信息,这样会不会造成资源浪费,两对管道是否可以完成这个任务?前者可以解决之前遇到的只读取第一个子程序的问题。[Quote=引用 1 楼 的回复:]

close(mtspipe[0]); //close read of mtspipe
close(stmpipe[1]); //close write of stmpipe

这两个你父进程关了多少次了,而且stmpipe[1]不应该在循环内关闭,否则你让后面的都子进程怎么继承它。
[/Quote]
qq120848369 2012-06-16
  • 打赏
  • 举报
回复
for (; i < pCount; ++i) {
int status;
while (-1 == waitpid(pid[i], &status, 0));
if (WIFEXITED(status))
printf("Child exited with code %d\n", WEXITSTATUS(status));
else if (WIFSIGNALED(status))
printf("Child terminated abnormally, signal %d\n", WTERMSIG(status));
}

再就是这里,你应该判断-1的情况下errno是什么,EINTR不应该让++i发生。
qq120848369 2012-06-16
  • 打赏
  • 举报
回复
close(mtspipe[0]); //close read of mtspipe
close(stmpipe[1]); //close write of stmpipe

这两个你父进程关了多少次了,而且stmpipe[1]不应该在循环内关闭,否则你让后面的都子进程怎么继承它。
这是一门linux下c++通讯架构实战课程,针对c/c++语言已经掌握的很熟并希望进一步深造以将来用c++在linux下从事网络通讯领域/网络服务器的开发和架构工作。这门课程学习难度颇高但也有着极其优渥的薪水(最少30K月薪,最高可达60-80K月薪),这门课程,会先从nginx源码的分析和讲解开始,逐步开始书写属于自己的高性能服务器框架代码,完善个人代码库,这些,将会是您日后能取得高薪的重要筹码。本课程原计划带着大家逐行写代码,但因为代码实在过于复杂和精细,带着写代码可能会造成每节课至少要4~5小时的超长时间,所以老师会在课前先写好代码,主要的时间花费在逐行讲解这些代码上,这一点望同学们周知。如果你觉得非要老师领着写代码才行的话,老师会觉得你当前可能学习本门课程会比较吃力,请不要购买本课程,以免听不懂课程并给老师差评,差评也会非常影响老师课程的销售并造成其他同学的误解。 这门课程要求您具备下面的技能:(1)对c/c++语言掌握的非常熟练,语言本身已经不是继续学习的障碍,并不要求您一定熟悉网络或者linux;(2)对网络通讯架构领域有兴趣、勇于挑战这个高难度的开发领域并期望用大量的付出换取高薪;在这门课程中,实现了一个完整的项目,其中包括通讯框架和业务逻辑框架,浓缩总结起来包括如下几点:(1)项目本身是一个极完整的多线程高并发的服务器程序;(2)按照包头包体格式正确的接收客户端发送过来的数据包, 完美解决收包时的数据粘包问题;(3)根据收到的包的不同来执行不同的业务处理逻辑;(4)把业务处理产生的结果数据包正确返回给客户端;本项目用到的主要开发技术和特色包括:(1)epoll高并发通讯技术,用到的触发模式是epoll中的水平触发模式【LT】;(2)自己写了一套线程池来处理业务逻辑,调用适当的业务逻辑处理函数处理业务并返回给客户端处理结果;(3)线程之间的同步技术包括互斥量,信号量等等;(4)连接池中连接的延迟回收技术,这是整个项目中的精华技术,极大程度上消除诸多导致服务器程序工作不稳定的因素;(5)专门处理数据发送的一整套数据发送逻辑以及对应的发送线程;(6)其他次要技术,包括信号、日志打印、fork()进程、守护进程等等;

23,125

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧