【发布时间】:2010-12-14 21:29:58
【问题描述】:
我不确定我是否在这里吠叫了正确的树...但是就这样吧。
我正在尝试将数据从我的父进程传递给所有子进程。它是一个简单的服务器程序,基本上会保留一个已连接客户端的列表,然后将已连接客户端的路由表发送给每个客户端。这最终将包含有关每个客户端的信息结构......但现在我只想让每个分叉进程从父进程那里获取相同的信息。
在父进程中,首先我设置我的管道并将它们设置为非阻塞(当管道中没有任何新数据可用时)。与客户端建立连接后,条目变量的数量会增加以反映此新连接。然后,我将一个子进程派生到一个新函数,并使用新的表条目数更新我的管道数组(我现在有 10 个管道,看看是否需要为每个子进程保留一个单独的管道)。
pid_t pid;
int numchildren;
int i, n;
/* Create the pipes. */
for(i = 0; i < 10; i++)
{
if (pipe (mypipe[i]))
{
fprintf (stderr, "Pipe failed.\n");
return EXIT_FAILURE;
}
}
for(i = 0; i < 10; i++)
{
for(n=0; n<2; n++)
{
// Get previous flags
int f = fcntl(mypipe[i][n], F_GETFL, 0);
// Set bit for non-blocking flag
f |= O_NONBLOCK;
// Change flags on fd
fcntl(mypipe[i][n], F_SETFL, f);
}
//close(mypipe[i][0]);
}
pid = fork();
if (pid == (pid_t) 0)
{
close (mypipe[numentries-1][1]);
recievecmds(new_fd, mypipe[numentries-1][0]);
close(new_fd);
return EXIT_SUCCESS;
}
else if (pid < (pid_t) 0)
{
fprintf (stderr, "Fork failed.\n");
return EXIT_FAILURE;
}
else
{
sprintf (buf,"%d",numentries);
for(i = 0; i < 10; i++)
write(mypipe[i][1], buf, strlen(buf));
memset(&buf, 0, sizeof buf);
}
然后我尝试在 recievecmds() 函数中读取管道中的内容:
nbytes = read(mypipe[childindex][0], buf, sizeof(buf));
第一个连接的客户端告诉我 numentries = 1,第二个客户端告诉我 numentries = 2,依此类推。我的意思是我什至看不到管道的意义,因为似乎无论我放入管道中的什么,我都可以将它传递到我在 fork 上调用的函数中。我会以错误的方式解决这个问题吗?试图弄清楚这一点非常令人沮丧。如何让我的所有子进程从我的父进程同时更新?
非常感谢您。
edit - 我的主要问题是我每次都在无限循环中重新声明管道。非常愚蠢的错误,立即意识到这可能是我问题的根源。然而,虽然现在第一个子/管道组合包含正确的数据......第二个没有。我会看看我是否可以自己解决这个问题,谢谢您的建议!
当然,现在我遇到了问题,因为我手动选择了一个选项来从管道中获取数据。我将不得不想出一种方法,要么在每次更新时获取所有管道的数据,要么确保只获取最新数据(可能一次只获取一个字符)。
感谢你们容忍我!我很抱歉没有发布整个程序......但是有很多。我绝对应该提到我有一个无限循环。
【问题讨论】:
-
您提到,当您可以进行函数调用时,您不确定为什么需要管道。请记住,每次 fork 一个新进程时,它都会获得父级数据的副本;不同的孩子得到不同的副本。而且,这些都是单独的过程;不要让父母和孩子的代码位于同一个文件中这一事实欺骗了您。使用 IPC 很困难,尤其是当您是新手时 - 祝您好运! :-)
-
@EmerickRogul:我喜欢以积极、鼓励的方式帮助他人。继续努力吧。 :)