如何在 POSIX 信号量中使用同步?

How do I use Synchronization in POSIX semaphores?

我已经读到 操作系统概念 中的第 6 章(死锁),作者是 Silbersechatz、Galvin 和 Gagne。我正在尝试制作一个程序,将车辆创建为穿过单向桥向北或向南的单独线程。如果桥上有车辆,那 vehicle/thread 就会睡觉(就像过桥一样)。我有点纠结汽车什么时候可以开(或过桥)。

#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;
}

我的问题肯定是 in/with goodToCross 信号量 - 我不知道如何正确定义它。

抱歉,无法以我的名义发表评论。

正如@bnaecker 所说,您只需要一个信号量。这是为了跟踪桥梁是否处于最大占用状态。假设一次只有一辆车在桥上,当一辆车第一次在桥上等待信号量时,它将递减计数器并继续过桥。之后,当汽车还在桥上时,任何其他试图过桥的汽车也会呼叫 wait。这一次,每辆车都将挂起(或忙等待),直到桥信号量再次递增(当当前在桥上的汽车退出时)。

届时,另一辆车将退出等待并减少计数器。

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