我有一个有5个子进程的父进程。我想向每个子进程发送一个随机变量。每个孩子都会对变量进行平方并将其发送回父母,而父母则将它们汇总在一起。
这甚至可能吗?我无法弄明白......
编辑:此过程将使用共享内存。
答案 0 :(得分:6)
有很多方法可以做到这一点,所有这些都涉及某种形式的进程间通信。您选择哪一个取决于许多因素,但有些因素是:
popen
等)。一般来说,在产生孩子之前,我可能会popen
在父母的一些通讯会话中;父母将知道所有五个,但每个孩子可以配置为只使用一个。
共享内存也是可能的,虽然你可能每个孩子都必须有几个值来确保通信顺利进行:
在所有情况下,您需要一种方法让孩子们只接受他们的价值观,而不是那些运往其他孩子的价值观。这可能就像向共享内存块添加值以存储子进程的PID一样简单。所有孩子都会扫描块中的每个元素,但只会处理状态为1且PID为其PID的那些元素。
例如:
这给出了一个并行度量,每个孩子不断监视共享内存以进行工作,Main将工作放在那里并定期收到结果。
答案 1 :(得分:3)
最糟糕的方法使用vfork()
并让不同的孩子在退出之前践踏记忆的不同部分;然后,父母只是将修改后的内存位相加。
非常不推荐 - 但是我遇到vfork()
可能实际使用的唯一情况。
为了娱乐(我的),我把它编码了:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/wait.h>
int main(void)
{
int i;
int array[5];
int square[5];
long sum = 0;
srand(time(0));
for (i = 0; i < 5; i++)
{
array[i] = rand();
if (vfork() == 0)
{
square[i] = array[i] * array[i];
execl("/bin/true", "/bin/true", (char *)0);
}
else
wait(0);
}
for (i = 0; i < 5; i++)
{
printf("in: %d; square: %d\n", array[i], square[i]);
sum += square[i];
}
printf("Sum: %d\n", sum);
return(0);
}
这很有效。使用“exit(0)
”代替“execl()
”的先前试用版无效;方阵是全零。示例输出(Solaris 10,SPARC上的32位编译):
in: 22209; square: 493239681
in: 27082; square: 733434724
in: 2558; square: 6543364
in: 17465; square: 305026225
in: 6610; square: 43692100
Sum: 1581936094
有时,总和会溢出 - 处理这个问题还有很大的改进空间。
“vfork()
”的Solaris手册页说:
与fork()函数不同,子进程借用 父母的记忆和控制线程直到打电话给 execve()或退出(异常或通过调用 _exit()(参见exit(2))。在此期间进行的任何修改 反映了子进程中内存的任何部分的时间 在从vfork()返回的父进程中。父母 当孩子使用其资源时,该过程暂停。
这可能意味着我的代码中不需要“wait()
”。 (但是,尝试简化代码似乎使其行为不确定。i
不会过早改变是非常重要的; wait()
确实确保了同步性。使用_exit()
代替{ {1}}似乎也破坏了事情。如果你重视自己的理智,或者如果你想要为你的家庭作业留下任何分数,就不要使用execl()
。)
答案 2 :(得分:0)
像the anti thread之类的东西可能会让你更容易一些,请参阅示例(特别是ns查找程序)。