C,rand函数与sleep()函数不兼容

时间:2016-03-26 00:21:28

标签: c random sleep

首先,我知道有很多关于rand()函数的问题,但我认为这是不同的。

实际上,当我没有与sleep()函数结合使用时,rand()函数总能正常工作。我尝试过这个。但是,当我将rand()函数与sleep()结合使用时,就像这样“睡眠(rand()%5)”,有时它会产生所有子进程的随机时间,正如我预期的那样,但有时适用于前4-5个孩子,之后,它为所有剩余子进程生成0。所以其他子进程不会睡觉。有时候,所有子流程的产品总是为0。

BTW,我在Ubuntu 64bit上编码。

关于我的代码: 我想从父进程中分叉8个子进程并逐个打印他们的pid号。但我应该在创建一个孩子后使用睡眠功能。睡觉时间应该是随机的。我使用time()函数作为种子并尝试使用rand函数,但它对睡眠函数不起作用。

这是我的代码:

#include <stdio.h>
#include <sys/sem.h>
#include <unistd.h>
#include <wait.h>
#include <stdlib.h>
#include <time.h>


void childs();
void parent();


int id;
int i;
int pidID[9];
int fd[2];
char buff[100];
int main(int argc, char *argv[]){
    pid_t child;
    for(i = 0; i < 8; i++){
        pipe(fd);

        child = fork();
        wait(NULL);
        if(child){
            parent();
            continue;
        }else if(child == 0){
            childs();
            break;
        }else{
            perror("State\n");
            exit(1);
        }
    }
    if(child ==0){
    printf("I am a child pid: %d, ppid: %d pidno: %d\n", getpid(), getppid(),pidID[i+1]);
    }else{
    printf("I am a parent pid: %d, ppid: %d pidno: %d\n", getpid(), getppid(),pidID[0]);
    }

}


void childs(){
id = getpid();
pidID[i + 1] = id;
char swap[50];
sprintf(swap, "%d" ,id);
write(fd[1], swap, 10);
srand(time(NULL));
int randomTime = rand() %5;
printf("Random time: %d\n",randomTime);
sleep(randomTime);
}



void parent(){
pidID[0] = getpid();
read(fd[0], buff , 10);
printf("Buff: %s\n", buff);
}

1 个答案:

答案 0 :(得分:2)

当您在每个子进程中time(NULL) sleep时,在同一秒内启动的所有子进程将以相同的值播种。

当然,如果涉及waitsleep,如果孩子们rand() % 5一秒钟,那么他们会以新的价值播种,所以事情大部分都会解决如果你总是在睡觉。

但是time产生0到4之间的值;第一次给定rand()种子会导致第一个time输出为五的倍数,你睡眠0秒,孩子几乎立即退出,并且循环分叉一个新的孩子,全部在最多只有几毫秒的空间。并且它将继续执行此操作一秒(或更多),直到rand重新设置将int randomTime = rand() %5; 的第一个输出更改为不是五的倍数的值。

如果你想解决这个问题,最简单的(如果仍然是愚蠢的)方法就是改变:

int randomTime = rand() %5 + 1; // Range 1-5, or use rand() % 4 + 1 for 1-4

为:

time

所以你永远不会有不到一秒钟的睡眠时间,并且你永远不会进入不断重新播种的病理情况,同时反复产生相同的零秒睡眠。

或者,如果必须有零秒睡眠,则使用更细粒度的struct timespec tm; clock_gettime(CLOCK_MONOTONIC, &tm); // xor-ing with tv_nsec >> 31 to ensure even low precision clocks vary // the low 32 bits srand((unsigned)(tm.tv_sec ^ tm.tv_nsec ^ (tm.tv_nsec >> 31))); 函数来获得更快速变化的种子。例如,在POSIX系统上,您可以改为使用clock_gettime,它应该变化得更快:

rand() % 5

并且您可以继续使用srand,因为tv_nsec之间的时间应足够长,以便更改{{1}}中的一些值并获得不同的种子值。