繁体   English   中英

分叉的过程,信号量,为什么要输出?

[英]forked processes, semaphores, why this output?

我有一个char类型的数组boxIn[] ,其中包含RRGBGBOYOOPR字符。 boxIn[]在共享内存中。 共享内存p还有一个char* ,其值为boxIn[]数组中char之一。

程序中定义了两个信号量,如下所示:

/* initialize semaphores */
if((sem_init(&sem, pshared, value)) == 1){      /* only 2(value) processes at the same time */
    perror("Error initializing synch semaphore\n");
    exit(1);
}
if((sem_init(&mutex, pshared, 1)) == 1){        /* only 1 processes at the same time */
    perror("Error initializing synch semaphore\n");
    exit(1);
}

我从for循环中派生孩子:

/* fork child processes */
for(i=0; i<n ; i++){
    pid = fork();
    if(pid < 0){    /* check for error  */
        printf("Fork error.\n");
    }
    else if(pid == 0) break;    /* child processes */

}

然后,我让孩子们做一些处理。 目前,我正试图逐步实现自己的目标。 因此,我只更改*p的值一次。

/******************************************************/
/******************   PARENT PROCESS   ****************/
/******************************************************/
if(pid != 0){
    while(wait()>0);
}

/******************************************************/
/******************   CHILD PROCESS   *****************/
/******************************************************/
else{
    while(*p != boxIn[i]); /* wait until it's my turn */
    sem_wait(&sem);
    printf("%c boxes are being painted.\n",boxIn[i]);
    printf("Done painting.\n");
    sleep(1);
    sem_wait(&mutex);
    if(*p=='R') *p='G';
    sem_post(&mutex);
    sem_post(&sem);
    exit(1);
}

但是我确实得到了意外的输出:

我期望的是:

R boxes are being painted.
R boxes are being painted.
Done.
Done.
R boxes are being painted.
Done.
G boxes are being painted.
G boxes are being painted.
Done.
Done.

我得到的如下:

R boxes are being painted.
Done painting.
R boxes are being painted.
Done painting.
R boxes are being painted.
Done painting.
G boxes are being painted.
Done painting.
G boxes are being painted.
Done painting.
varaquilex@computer ~/Dropbox/Courses/BLG312E - Computer Operating Systems/hw3 $ G boxes are being painted.
Done painting.
G boxes are being painted.
Done painting.
G boxes are being painted.
Done painting.
G boxes are being painted.
Done painting.
G boxes are being painted.
G boxes are being painted.
Done painting.
Done painting.
G boxes are being painted.
Done painting.
G boxes are being painted.
Done painting.
P boxes are being painted.
Done painting.
P boxes are being painted.
Done painting.
P boxes are being painted.
Done painting.
P boxes are being painted.
Done painting.
P boxes are being painted.
Done painting.
^C

问题是:为什么会超过2个G框画,即使只有2 G中框boxIn[]数组,更重要的是我怎么甚至可以P框画,何况只有一个P盒阵列,我得到了很多P盒的油漆?

注意 :我已经尝试了很长时间。 更不用说我使用shift + C在此之前停止了许多程序。 我重新启动终端并获得此输出。 更有趣的一点是,我尝试将i的值与要绘制的框一起打印,然后我看到输出混淆了! 我的意思是,即使有printf()printf("%c boxes(%d) are being painted",boxIn[i],i); ,也有一些行显示G boxes(3) are being painted ,还有一些G boxes(3) are being painted G boxes are being painted printf("%c boxes(%d) are being painted",boxIn[i],i); 这很尴尬,我重新启动了操作系统,并从同一程序获得了不同的输出。 有人可以解释一下为什么会发生这种情况,如何防止这种情况再次发生?

为了使用进程共享的信号量,它们必须位于共享内存中。 你不是。 因此,在派生之后,每个进程都有其自己的信号量副本。 分配共享内存的最简单方法是:

sem_t *sem = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE,
                  MAP_SHARED|MAP_ANONYMOUS, -1, 0);

但是,尽管几乎可以普遍使用,但匿名映射并未在POSIX中指定,因此正式地是“不可移植的”。 实现此目的的另一种可移植方式是制作一个临时文件或POSIX共享内存对象。

或者( 推荐的方法)使用sem_open而不是sem_init

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM