首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C,rand函数不能正常工作

C,rand函数不能正常工作
EN

Stack Overflow用户
提问于 2016-03-26 00:21:28
回答 1查看 8.8K关注 0票数 1

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

实际上,rand()函数在没有与when ()函数组合时总是正常工作。我试过了。但是,当我将rand()函数和well ()这样的“睡眠(rand() %5)”组合在一起时,有时会像我预期的那样为所有子进程生成随机时间,但有时对前4-5个子进程很好,然后它为所有剩余的子进程生成0。所以其他的子进程不睡觉。有时,它总是为所有子进程生成0。

顺便说一句,我在Ubuntu 64位上编码。

关于我的代码:我想把8个子进程从父进程中分送出来,然后一个一个地打印出他们的pid数字。但是我应该在创造一个孩子之后使用睡眠功能。睡眠时间应该是随机的。我使用time()函数作为种子,并尝试使用rand函数,但是睡眠功能不能正常工作。

这是我的代码:

代码语言:javascript
复制
#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);
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-26 00:32:36

当您在每个子进程中使用srandtime(NULL)时,在同一秒钟内启动的所有子进程都将具有相同的值。

当然,在涉及到sleepwait的情况下,如果孩子们在sleep上稍等片刻,他们就会有一个新的值,所以如果你总是在睡觉的话,事情基本上就会解决。

但是rand() % 5会产生介于0到4之间的值;当给定的time种子第一次导致第一个rand()输出为5的倍数时,您就可以睡上0秒钟,子节点几乎立即退出,并且循环会分叉一个新的子节点,这一切最多只需几毫秒。并且它将在一个坚实的秒(或更多)内继续这样做,直到timerand的第一个输出更改为一个不是5的倍数的值。

如果您想修复这个问题,最简单的(如果仍然是愚蠢的)方法是更改:

代码语言:javascript
复制
int randomTime = rand() %5;

至:

代码语言:javascript
复制
int randomTime = rand() %5 + 1; // Range 1-5, or use rand() % 4 + 1 for 1-4

所以你的睡眠时间永远不会少于一秒钟,你也不会进入这样的病理性病例,那就是,不断地重复播种同样的时间,产生相同的零秒睡眠。

或者,如果零秒睡眠必须是一种可能性,使用一个更细粒度的time函数来获得一个变化更快的种子。例如,在POSIX系统上,您可以使用clock_gettime,它应该变化得更快:

代码语言:javascript
复制
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)));

您可以继续使用rand() % 5,因为srand之间的时间应该足够长,可以更改tv_nsec中的几个值并获得不同的种子值。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36230140

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档