#include #include #include #include struct CarInfo { int id; int dir; }; pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t s_n = PTHREAD_COND_INITIALIZER; pthread_cond_t n_s = PTHREAD_COND_INITIALIZER; pthread_cond_t *cq[2] = { &s_n, &n_s }; char *sdir[] = { "south", "north" }; int cars_on_bridge = 0; int dir_on_bridge = -1; //0: south->north; 1:north->south; -1:bridge empty void *car_thread (void *p) { struct CarInfo *car = p; pthread_mutex_lock(&m); while (cars_on_bridge > 2 || (dir_on_bridge != -1 && dir_on_bridge != car->dir)) pthread_cond_wait(cq[car->dir], &m); cars_on_bridge++; dir_on_bridge = car->dir; printf("Car %2d on bridge, going %s, on bridge %d car(s) (to %s)\n", car->id, sdir[car->dir], cars_on_bridge, sdir[dir_on_bridge]); pthread_mutex_unlock(&m); usleep(5000000); pthread_mutex_lock(&m); cars_on_bridge--; printf("Car %2d off bridge, going %s, on bridge %d car(s) (to %s)\n", car->id, sdir[car->dir], cars_on_bridge, sdir[dir_on_bridge]); if (cars_on_bridge > 0) { pthread_cond_signal(cq[car->dir]); } else { dir_on_bridge = -1; pthread_cond_broadcast(cq[1 - car->dir]); } pthread_mutex_unlock(&m); free(car); } int main () { pthread_t thr_id; pthread_attr_t attr; int car_id = 0; struct CarInfo *car; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); while (1) { car = malloc(sizeof(struct CarInfo)); car->id = ++car_id; car->dir = rand() & 1; printf("New car %d arrived from %s\n", car_id, sdir[1 - car->dir]); pthread_create(&thr_id, &attr, car_thread, (void *) car); usleep(2000000); } return 0; }