信号量和printf的行为不符合我的预期

时间:2013-12-03 10:29:53

标签: c printf semaphore

我的问题是关于以下代码:

/* 
 * File:   main.c
 * Author: Wilbert
 *
 * Created on December 2, 2013, 7:41 PM
 */
#define _POSIX_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
#include <sys/types.h>
#include <time.h>

/*
 * 
 */

#define SHARED 1
#define MAX_NUMBER_OF_BABOONS 5
#define MUTEX 1
#define TRUE 1
sem_t baboon_westbound;
sem_t baboon_eastbound;
sem_t baboon_cord_mutex;
sem_t print_mutex;
int pipe1[2];
int pipe2[2];
char buffer[5];
unsigned char ch=0;

void baboon_produce_westward(){
    int random_wait = rand() % 5;
    sleep(random_wait);
    int i = 0;
    if(sem_wait(&baboon_cord_mutex)==-1) perror("Error on cord mutex");
    while(TRUE){
        i++;
        if(sem_wait(&print_mutex)==-1) perror("Error on wait print mutex");
        printf("Baboon %d heading westward\n",i%10);
        sprintf(buffer,"%d",i%10);
        if(write(pipe1[1],buffer,i)==-1) perror("Error writing to pipe.\n");
        buffer[0]='\0';
        if(sem_post(&print_mutex)==-1) perror("Error on post print mutex");
        sleep(1);
    }
}

void baboon_done_westward(){
    while(TRUE){
        if(read(pipe1[0],buffer,1)>0){
            if(sem_post(&baboon_westbound)==-1) perror("Error on post westbound");
            if(sem_wait(&print_mutex)==-1) perror("Error on wait print mutex");
            printf("Baboon %s off the rope on west side.\n",buffer);
            if(sem_post(&print_mutex)==-1) perror("Error on post print mutex");
        }
    }
}

void baboon_produce_eastward(){
    int random_wait = rand() % 5;
    sleep(random_wait);
    int i = 0;
    sem_wait(&baboon_cord_mutex);
    while(TRUE){
        i++;
        if(sem_wait(&print_mutex)==-1) perror("Error on wait print mutex");
        printf("Baboon %d heading eastward\n",i%10);
        sprintf(buffer,"%d",i%10);
        if(write(pipe2[1],buffer,i)==-1) perror("Error writing to pipe.\n");
        if(sem_post(&print_mutex)==-1) perror("Error on post print mutex");
        sleep(1);
    }
}

void baboon_done_eastward(){
    while(TRUE){
        if(read(pipe2[0],buffer,1)>0){
            if(sem_wait(&print_mutex)==-1) perror("Error on wait print mutex");
            printf("Baboon %s off the rope on east side.\n",buffer);
            if(sem_post(&print_mutex)==-1) perror("Error on post print mutex");
        }
    }
}

int main(int argc, char** argv) {
    int status;
    if(sem_init(&baboon_westbound,SHARED,MAX_NUMBER_OF_BABOONS)==-1) perror("Error initiating semaphore");
    if(sem_init(&baboon_eastbound,SHARED,MAX_NUMBER_OF_BABOONS)==-1) perror("Error initiating semaphore");
    if(sem_init(&baboon_cord_mutex,SHARED,MUTEX)==-1) perror("Error initiating semaphore");
    if(sem_init(&print_mutex,SHARED,MUTEX)==-1) perror("Error initiating semaphore");
    if(pipe(pipe1)==-1 || pipe(pipe2)==-1){
            perror("Pipe call");
            exit(1);
    }

    switch(fork()){
        case -1:
            perror("Fork call #1");
            exit(2);
        case 0:
            baboon_produce_westward(0);
            break;
        default:
            switch(fork()){
                case -1:
                    perror("Fork call #2");
                    exit(2);
                case 0:
                    baboon_done_westward();
                    break;
                default:
                    switch(fork()){
                        case -1:
                            perror("Fork call #2");
                            exit(2);
                        case 0:
                            baboon_produce_eastward();
                            break;
                        default:
                            switch(fork()){
                                case -1:
                                    perror("Fork call #2");
                                    exit(2);
                                case 0:
                                    baboon_done_eastward();
                                    break;
                                default:
                                    wait(&status);          
                            }
                    }
            }
    }

}

由于某种原因,我给出了以下输出:

Baboon 1 heading eastward
Baboon 1 off the rope on east side.
Baboon 1 heading westward
Baboon 1 off the rope on west side.
Baboon 2 heading eastward
Baboon 2 off the rope on east side.
Baboon  off the rope on east side.
Baboon 2 heading westward
Baboon 2 off the rope on west side.
Baboon  off the rope on west side.
Baboon 3 heading eastward
Baboon 3 off the rope on east side.
Baboon  off the rope on east side.
Baboon  off the rope on east side.
Baboon 3 heading westward
Baboon 3 off the rope on west side.
Baboon  off the rope on west side.
Baboon  off the rope on west side.
Baboon 4 heading eastward
Baboon 4 off the rope on east side.
Baboon  off the rope on east side.
Baboon  off the rope on east side.
Baboon  off the rope on east side.
Baboon 4 heading westward
Baboon 4 off the rope on west side.
.
.
.

有两件事令我困惑:

1)baboon_cord_mutex以值1启动,根据我的理解,这意味着如果某个进程执行sem_wait(&baboon_cord_mutex),则后续执行相同操作的任何其他进程将被阻止,直到某个进程执行sem_post(&baboon_cord_mutex)

尽管如此,我从不打电话给sem_post(&amp; baboon_cord_mutex),因为我的计划只是在两个人中的一个开始生产狒狒时阻止另一方,但仍有两个产生狒狒的过程正在运行。

2)我正在做baboon_done_eastward()baboon_done_westward()

if(read(pipe#[0],buffer,1)>0)在进行任何打印之前,这意味着应该将某些内容写入缓冲区以便if中的代码运行,但是我得到的多个打印输出似乎暗示缓冲区为空,原因没有打印号码。

最后,我正在编写以下方式:

gcc main.c -Wall -pedantic -std=c99 -D_XOPEN_SOURCE=700 -pthread

任何帮助将不胜感激。我确信这是一些我缺少的细节,但似乎无法弄清楚它是什么。

0 个答案:

没有答案