我有一个boxIn[]类型的数组,它包含char个字符。R R G B G B O Y O O P R在共享内存中。共享内存中还有一个值为boxIn[]数组中char*s之一的p
程序中定义了两个信号量,如下所示:

/* 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);
}

我把孩子们从一个循环中分离出来:
/* 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 */

}

然后我让孩子们做一些处理。目前我正努力一步一步地达到我的目标。因此,我只更改一次char的值。
/******************************************************/
/******************   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

问题是:尽管boxIn[]数组中只有2个for框,但为什么要绘制2个以上的*p框,更重要的是,如何绘制G框,更不用说数组中只有一个G框,并且绘制了许多boxIn[]框?
注:我已经试了很长时间了。更不用说在这之前我用了shift+c来停止很多程序。我重新启动终端,得到这个输出。更有趣的一点是,我试着把P的值和正在绘制的框一起打印出来,我看到输出是混合的!我是说,有些行显示P,有些行显示P,即使iG boxes(3) are being painted。这很尴尬,我重新启动了操作系统,从同一个程序得到了不同的输出。有人能解释一下为什么会发生这种情况,我怎样才能防止这种情况再次发生?

最佳答案

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

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

然而,尽管匿名映射几乎是普遍可用的,但它并没有在posix中指定,因此在形式上“不可移植”。另一种可移植的方法是创建一个临时文件或posix共享内存对象。
或者(这里是推荐的方法),使用sem_open而不是sem_init

关于c - fork 的过程,信号量,为什么要输出?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16387348/

10-11 22:33
查看更多