[英]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.