如何在 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 中的实现,所以我将把它留在对过程的高级描述中。
我已经读到 操作系统概念 中的第 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 中的实现,所以我将把它留在对过程的高级描述中。