分叉后为每个孩子生成随机等待时间
我在这里有这个源代码,它有一个必需的随机数生成函数,称为randG(); 问题是当我分叉 5 个孩子并在每个孩子中调用该函数 5 次时,我得到了 5 次相同的数字。有没有办法解决这个问题?我需要每个数字都是单独的和具体的。谢谢!
source code:
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <stdlib.h>
#include <math.h>
int randG(int mean, int stddev) {
double mu = 0.5 + (double) mean;
double sigma = fabs((double) stddev);
double f1 = sqrt(-2.0 * log((double) rand() / (double) RAND_MAX));
double f2 = 2.0 * 3.14159265359 * (double) rand() / (double) RAND_MAX;
if (rand() & (1 << 5))
return (int) floor(mu + sigma * cos(f2) * f1);
else
return (int) floor(mu + sigma * sin(f2) * f1);
}
int perform() {
int mean[2] = {
9,
11
};
int stdDev[2] = {
3,
7
};
int semID;
int procID;
int eatI;
int thinkI;
int eatTime[6] = {0, 0, 0, 0, 0, 0};
int thinkTime[6] = {0, 0, 0, 0, 0, 0};
//printf("%d n", (0 % 4));
struct sembuf using[5] = { {0, -1, 0}, {1, -1, 0}, {2, -1, 0}, {3, -1, 0}, {4, -1, 0} };
struct sembuf use[5] = { {0, 1, 0}, {1, 1, 0}, {2, 1, 0}, {3, 1, 0}, {4, 1, 0} };
semID = semget(IPC_PRIVATE, 5, IPC_CREAT | 0600);
for (int dan = 0; dan < 5; dan++) {
semop(semID, & use[dan], 1);
printf("%d n", (randG(11, 7)));
}
for (int x = 0; x < 5; x++) {
procID = fork();
int philNo = x + 1;
if (procID == 0) {
} else {
// thinking
sleep(rand() % 2);
thinkI = randG(11, 7);
thinkTime[x] = thinkTime[x] + thinkI;
printf("philosopher No: %d is thinking for: %d sec total of: %d n", philNo,
thinkI, thinkTime[x]);
sleep(thinkI); // think for the amount of seconds randomly
// generated by the randG (random gaussian) formula.
// thinking end.
// eating
semop(semID, & using[2], 1);
printf("snatching the second resource %d n", philNo);
semop(semID, & use[2], 1);
sleep(0.01);
// eating
exit(0);
}
}
}
int main(int argc, char
const * argv[]) {
perform();
return 0;
}
产生不想要的输出:
philosopher No: 1 is thinking for: 4 sec total of: 4
philosopher No: 2 is thinking for: 4 sec total of: 4
philosopher No: 3 is thinking for: 4 sec total of: 4
philosopher No: 4 is thinking for: 4 sec total of: 4
philosopher No: 5 is thinking for: 4 sec total of: 4
回答
之后,fork()每个子节点都将以与分叉之前父节点完全相同的随机数生成器状态开始。您需要srand在孩子中再次为随机数生成器重新设定种子。一个很好的数字是子进程 id,因为它肯定与同时运行的其他子进程不同。
如果使用 pthread 库没有问题,这可以通过注册pthread_atfork用于新创建的子例程的播种函数来自动化。