C 使用fork()生成随机数
我的程序应该有n个子进程,这些子进程每秒生成一个介于1和9之间的随机数,我的问题是我应该验证这个子进程是否在同一时间生成相同的数 例如,如果我有5个孩子,他们可以生成 5 4 8 2 1 但它们不能产生 55431 有人能给我建议吗C 使用fork()生成随机数,c,random,process,fork,sleep,C,Random,Process,Fork,Sleep,我的程序应该有n个子进程,这些子进程每秒生成一个介于1和9之间的随机数,我的问题是我应该验证这个子进程是否在同一时间生成相同的数 例如,如果我有5个孩子,他们可以生成 5 4 8 2 1 但它们不能产生 55431 有人能给我建议吗 int main (int argc,char** argv) { int i,pid,x,l; l=atoi(argv[1]); for(i=0;i<l;i++) { pid=fork();
int main (int argc,char** argv)
{
int i,pid,x,l;
l=atoi(argv[1]);
for(i=0;i<l;i++)
{
pid=fork();
switch(pid)
{
case -1:
printf("error\n");
case 0: {
srand(time(NULL));
x=rand()%9+1;
printf("Im child%d\n",x);sleep(1);
}
default:
printf("Im parent %d\n",getpid());
}
}
}
您的子进程需要将它们选择的随机数传递给父进程。您可以使用管道在父进程和每个子进程之间建立双向通信 我坚持双向,因为如果孩子画错了号码,家长必须再次询问 这里是我不久前编写的一些样板代码,用于在父进程和子进程之间建立这样的双向通信。发生的情况是,父对象写入一个恰好是子对象“stdin”的文件,而子对象写入其stdout,该stdout也由父对象读取。技术上是C++,但易于适应C.P/P> 我不明白在子进程中生成随机数的可能用例是什么。也许您应该使用线程而不是进程
#include "process.h"
#include <assert.h>
#include <unistd.h>
#include <signal.h>
#include <cstring>
#include <iostream>
void Process::run(const char *cmd) throw (Err)
/*
* Spawn a child process, and executes cmd. On success:
* - pid is the process id
* - in, out are FILE* to read/write from/to the process' stdout/stdin
* */
{
pid = 0;
int readpipe[2], writepipe[2];
#define PARENT_READ readpipe[0]
#define CHILD_WRITE readpipe[1]
#define CHILD_READ writepipe[0]
#define PARENT_WRITE writepipe[1]
try {
if (pipe(readpipe) < 0 || pipe(writepipe) < 0)
throw Err();
pid = fork();
if (pid == 0) {
// in the child process
close(PARENT_WRITE);
close(PARENT_READ);
if (dup2(CHILD_READ, STDIN_FILENO) == -1)
throw Err();
close(CHILD_READ);
if (dup2(CHILD_WRITE, STDOUT_FILENO) == -1)
throw Err();
close(CHILD_WRITE);
if (execlp(cmd, cmd, NULL) == -1)
throw Err();
} else if (pid > 0) {
// in the parent process
close(CHILD_READ);
close(CHILD_WRITE);
if ( !(in = fdopen(PARENT_READ, "r"))
|| !(out = fdopen(PARENT_WRITE, "w")) )
throw IOErr();
} else
// fork failed
throw Err();
} catch (Err &e) {
cleanup();
throw;
}
}
void Process::cleanup()
{
// close file descriptors
if (in) fclose(in);
if (out) fclose(out);
// kill child process
if (pid > 0) kill(pid, SIGKILL);
}
Process::~Process()
{
cleanup();
}
void Process::write_line(const char *s) const throw(IOErr)
{
fputs(s, out);
fflush(out); // don't forget to flush! (that's what she says)
if (ferror(out))
throw IOErr();
}
void Process::read_line(char *s, int n) const throw(IOErr)
{
if (!fgets(s, n, in))
throw IOErr();
}
这是一个很酷的问题,因为它同时说明了随机数生成实际上不是随机的,以及单独线程的使用和限制 我只想记下几件事 1由于2个原因,您不能要求每个子进程拾取的随机数必须与其他进程协调。1他们将不再选择随机数字,他们将选择另一个进程尚未选择的数字;那是随机的?2如果所有子进程都必须与父进程协调,那么整个进程将比只有一个进程慢——换句话说,这是无用的,但这可能是练习的重点。也就是说,允许整体算法不是快速高效的,而是通过包含进程调度因子来增加随机性。如果没有,那么继续阅读 2每个流程是否可以全速运行,或者每个流程是否必须等待当前迭代完成所有其他流程?或者父进程可以简单地记录每个子进程在时隙n的拾取吗 3子进程不能超过9个,因为可以保证至少有2个进程选择相同的数字 那么,每个孩子是否可以使用相同的种子为伪随机数生成器设定种子,然后将其编号添加到mod 9中?它是随机的,因为它是一个伪随机数加上一个常数。唯一的缺点是它不是随机的,其他的孩子,但假设你不喜欢,然后我们回到观察1,它比较慢,仍然不是随机的,其他的孩子,因为它是协调的。它同样是随机的,因为rnd实际上是确定性的,它只是看起来是随机的 更新一些伪代码:
In the parent process
select a seed number S
for index = 0 .. numChildren - 1 do
fork child
childNum = index
communicate(S,childNum) to child
while true
receive(childRND,childNum,childIteration) from child
iterationResults[childIteration,childNum] = childRND
iterationResults[childIteration].numResults++
if(iterationResults[childIteration].numResults == numChildren) then
print iterationResults[childIteration]
delete iterationResults[childIteration]
子伪代码:
In each child process
Seed the random number generator with S
for iteration = 1 ... do
X = RND(1,9)
Y = RND(1,10000)
Pick the Yth number N that is relatively prime to 9 (or just pick the Yth prime)
childRND = (X + (Y*childNum mod 9)) mod 9 + 1
send(childRND,childNum,iteration) to parent
注:
由于所有子项都使用相同的种子S为RNG播种,因此每个子项的X和Y始终是相同的数字
因为Y相对于9是素数,所以N=0..8的N*Y mod 9将创建数字0..8的排列。由于我们选择了一个随机Y,排列也将是随机的,因此X+Y*childNum mod 9 mod 9+1将在每次新的迭代中进行置乱,但是每个子项都保证返回一个不同于其他子项的数字
是的,这仍然是确定的,但报告的结果会显得更加随机。因此您需要生成随机数,但您需要对其进行协调以避免重复,但您是在单独的过程中生成随机数的,这些过程似乎是专为防止您需要的那种协调而设计的?你想解决的实际问题是什么?如果每隔一秒钟就解决一次,那么1..9中的数字将很快被计算出来。如果一个孩子有@JohnZwinck,他们似乎不产生相同的数字,因为rand取决于时间,但是当我运行程序时,它们总是产生相同的编号,而不是以任何方式依赖时间。因为我使用SalDimeTimeTM。不知怎么说,我认为C++代码不会帮助OP更接近于解决他/她的问题的真实本质。我是C++的新手,但我会尝试采纳一个想法。