我有一个有 5 个子进程的父进程。我想向每个子进程发送一个随机变量。每个孩子将平方变量并将其发送回父母,父母将把它们加在一起。
这甚至可能吗?我想不通...
编辑:此过程将使用共享内存。
我有一个有 5 个子进程的父进程。我想向每个子进程发送一个随机变量。每个孩子将平方变量并将其发送回父母,父母将把它们加在一起。
这甚至可能吗?我想不通...
编辑:此过程将使用共享内存。
有很多方法可以做到这一点,都涉及某种形式的进程间通信。您选择哪一个将取决于许多因素,但其中一些是:
popen
等)。一般来说,popen
在产生孩子之前,我可能会在父母中进行多次交流;父母会知道所有五个,但每个孩子可以配置为只使用一个。
共享内存也是一种可能性,尽管您可能必须在每个孩子中有几个值以确保通信顺利进行:
在所有情况下,您都需要一种方法让孩子们只接受他们的价值观,而不是那些注定要给其他孩子的价值观。这可能就像向共享内存块添加一个值来存储孩子的 PID 一样简单。所有子节点都会扫描块中的每个元素,但只会处理状态为 1 且 PID 是其 PID 的元素。
例如:
这给出了并行度的度量,每个子进程持续监控共享内存的工作,Main 将工作放在那里并定期接收结果。
最讨厌的方法是使用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 上的 32 位编译,SPARC):
in: 22209; square: 493239681
in: 27082; square: 733434724
in: 2558; square: 6543364
in: 17465; square: 305026225
in: 6610; square: 43692100
Sum: 1581936094
有时,总和会溢出——在处理上还有很大的改进空间。
' ' 的 Solaris 手册页vfork()
说:
与 fork() 函数不同,子进程借用父进程的内存和控制线程,直到调用 execve() 或退出(异常或调用 _exit() (参见 exit(2))。任何修改在此期间对子进程内存的任何部分进行的操作都会在从 vfork() 返回时反映在父进程中。父进程在子进程使用其资源时暂停。
这可能意味着 ' wait()
' 在我的代码中是不必要的。(然而,试图简化代码似乎使它的行为不确定。它i
不会过早改变是相当重要的;wait()
确实确保同步性。使用_exit()
而不是似乎也破坏了事情。如果你重视你的理智,请execl()
不要使用-vfork()
或者如果你想为你的家庭作业打分。)
诸如反线程之类的东西可能会让您更容易,请参阅示例(特别是 ns 查找程序)。