POSIX sempahores:同步

时间:2017-10-11 20:43:49

标签: c multithreading posix semaphore

我已经在Silbersechatz,Galvin和Gagne的操作系统概念中获得了第6章(死锁)。我试图制作一个程序,将车辆作为单独的线程向北或向南穿过单向桥。如果桥上有车辆,该车/线将会睡觉(就像穿过桥一样)。当汽车好转(或过桥)时,我有点挣扎。

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <strings.h>
#include <semaphore.h>

#define MAX_WAIT 3 // how many seconds each car will wait at most

typedef struct _VEHICLE {
    pthread_t t;
    int isNorth;
    int idx;
    int waitfor;
} VEHICLE;

sem_t sem; // bridge
sem_t goodToCross = 1;

void enter_bridge(char* direction, int idx) {
    printf("1 - %s vehicle %d is about to enter the bridge\n", direction, idx);
    goodToCross.wait(&sem);
    printf("2 - %s vehicle %d has entered the bridge\n", direction, idx);
}

void exit_bridge(char* direction, int idx) {
  printf("5 - %s vehicle %d has left the bridge\n", direction, idx);

    goodToCross.signal(&sem);
}

void* pass_bridge(void* param) {
    VEHICLE* f = (VEHICLE*) param;
    char* direction = f->isNorth ? "North" : "South";

    enter_bridge(direction, f->idx);
    printf("3 - %s vehicle %d will pass the bridge in %d seconds\n", direction, f->idx, f->waitfor);
    sleep(f->waitfor);
    printf("4 - %s vehicle %d has passed the bridge in %d seconds\n", direction, f->idx);

    exit_bridge(direction, f->idx);
}

int main(int argc, char** argv) {
    int i;
    VEHICLE* v_north;
    VEHICLE* v_south;

    int nNorthVehicles, nSouthVehicles;

    if (argc != 3) {
      printf("Usage: ./main (Num North Vehicles) (Num South Vehicles)\n");
      return 1;
    }

    nNorthVehicles = atoi(argv[1]);
    nSouthVehicles = atoi(argv[2]);

    if (nNorthVehicles <= 0 || nSouthVehicles <= 0) {
      printf("Error number of vehicles given is not a valid number\n");
      return 1;
    }

    v_north = (VEHICLE*)malloc(sizeof(VEHICLE) * nNorthVehicles);
    v_south = (VEHICLE*)malloc(sizeof(VEHICLE) * nSouthVehicles);

    printf("we have %d vehicles from the north and %d vehicles the south\n", nNorthVehicles, nSouthVehicles);

    sem_init(&sem, 0, 1);

    for (i = 0; i < nNorthVehicles; ++i) {
      v_north[i].isNorth = 1;
      v_north[i].idx = 1;
      v_north[i].waitfor = rand() % MAX_WAIT;
      pthread_create(&(v_north[i].t), 0, pass_bridge, &(v_north[i]));
    }

    for (i = 0; i < nSouthVehicles; ++i) {
      v_south[i].isNorth = 0;
      v_south[i].idx = 1;
      v_south[i].waitfor = rand() % MAX_WAIT;
      pthread_create(&(v_south[i].t), 0, pass_bridge, &(v_south[i]));
    }

    for (i = 0; i < nNorthVehicles; ++i) {
      pthread_join(v_north[i].t, NULL);
    }

    for (i = 0; i < nSouthVehicles; i++) {
      pthread_join(v_south[i].t, NULL);
    }

    sem_destroy(&sem);

    printf("All vehicles have passed\n");

    free(v_north);
    free(v_south);

    return 0;
}

我的问题肯定在/ goodToCross信号量中 - 我无法弄清楚如何正确定义它。

1 个答案:

答案 0 :(得分:2)

抱歉,无法在我的声誉中添加评论。

就像@bnaecker所说的那样,你只需要一个信号量。这是为了跟踪桥是否处于最大占用率。假设一次只有一辆车可以在桥上,当汽车第一次在桥信号灯上等待时,它将减少计数器并继续穿过桥。在那之后,当汽车仍然在桥上时,任何其他试图穿越的车也会等待。这一次,每辆汽车都会挂起(或忙等待),直到桥信号灯再次增加(当桥上的汽车退出时)。

那时,另一辆车将不再等待并减少柜台。

编辑:我不确定c中信号量的实现,所以我只是将其留在过程的高级描述中。