```c #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #define CUSTOMERS 10 // 顾客数量 #define SEATS 10 // 等待座位数量 sem_t seats; // 空余座位数量的资源信号量 sem_t mutex; // 互斥信号量,用于实现对取号机的互斥访问 sem_t customer; // 顾客数量的资源信号量 void *customer_process(void *arg) { int id = *(int *)arg; sem_wait(&seats); // 等待有空座位 sem_wait(&mutex); // 锁住取号机 printf("顾客 %d 取号成功,等待叫号\n", id); sem_post(&mutex); // 释放取号机锁 sem_post(&customer); // 增加等待服务的顾客数 sem_wait(&mutex); // 锁住取号机,模拟等待服务 printf("顾客 %d 正在接受服务\n", id); sleep(rand() % 5 + 1); // 模拟服务时间 printf("顾客 %d 服务结束,离开银行\n", id); sem_post(&mutex); // 释放取号机锁 sem_post(&seats); // 释放座位 } void *teller_process(void *arg) { while (1) { sem_wait(&customer); // 等待有顾客需要服务 sem_wait(&mutex); // 锁住取号机,准备叫号 printf("营业员叫号,开始为顾客服务\n"); sem_post(&mutex); // 释放取号机锁 } } int main() { pthread_t customers[CUSTOMERS]; pthread_t teller; int ids[CUSTOMERS]; sem_init(&seats, 0, SEATS); // 初始化空余座位数量的资源信号量 sem_init(&mutex, 0, 1); // 初始化互斥信号量 sem_init(&customer, 0, 0); // 初始化顾客数量的资源信号量 for (int i = 0; i < CUSTOMERS; i++) { ids[i] = i + 1; pthread_create(&customers[i], NULL, customer_process, &ids[i]); } pthread_create(&teller, NULL, teller_process, NULL); for (int i = 0; i < CUSTOMERS; i++) { pthread_join(customers[i], NULL); } pthread_cancel(teller); sem_destroy(&seats); sem_destroy(&mutex); sem_destroy(&customer); return 0; } ``` 需要注意的逻辑点: 1. 信号量初始化:确保所有信号量在使用前都正确初始化,特别是资源信号量 `seats` 和 `customer`,它们的初始值应该反映实际的资源情况。 2. 互斥访问:使用互斥信号量 `mutex` 来保护共享资源(如取号机),防止多个线程同时访问导致数据不一致。 3. 服务顺序:营业员通过 `sem_wait(&customer)` 等待有顾客需要服务,确保每次只有一位顾客接受服务,避免并发问题。 [2024-12-13 14:42:20 | AI写代码神器 | 731点数解答]