empty = N:空槽位數 (生產者 P(empty)、V(empty))。full = 0:產品數 (消費者 P(full)、V(full))。mutex = 1:互斥鎖 (雙方 P(mutex) 進入臨界區、V(mutex) 離開)。
// 全域
semaphore empty = N, full = 0, mutex = 1;
item buffer[N];
int in = 0, out = 0;
producer() {
while (1) {
item next = produce();
P(empty); // 等待空槽
P(mutex); // 進入臨界區
buffer[in] = next;
in = (in + 1) % N;
V(mutex); // 離開臨界區
V(full); // 通知有產品
}
}
consumer() {
while (1) {
P(full); // 等待產品
P(mutex); // 進入臨界區
item next = buffer[out];
out = (out + 1) % N;
V(mutex); // 離開臨界區
V(empty); // 通知有空槽
consume(next);
}
}
#include
#include
#include
#define N 10
int buffer[N], in = 0, out = 0;
sem_t empty, full, mutex;
void *producer(void *arg) {
while (1) {
int item = rand() % 100;
sem_wait(&empty);
sem_wait(&mutex);
buffer[in] = item;
in = (in + 1) % N;
sem_post(&mutex);
sem_post(&full);
sleep(1);
}
}
void *consumer(void *arg) {
while (1) {
sem_wait(&full);
sem_wait(&mutex);
int item = buffer[out];
out = (out + 1) % N;
sem_post(&mutex);
sem_post(&empty);
printf("消費: %d\n", item);
sleep(2);
}
}
int main() {
sem_init(&empty, 0, N);
sem_init(&full, 0, 0);
sem_init(&mutex, 0, 1);
pthread_t p1, p2, c1;
pthread_create(&p1, NULL, producer, NULL);
pthread_create(&p2, NULL, producer, NULL);
pthread_create(&c1, NULL, consumer, NULL);
pthread_join(p1, NULL); // 永不返回
return 0;
}
編譯:gcc pc.c -lpthread -o pc
CreateSemaphore, WaitForSingleObject, ReleaseSemaphore。CreateMutex, WaitForSingleObject, ReleaseMutex。CreateThread / _beginthreadex。P(empty) 在 P(mutex) 之前,避免滿緩衝區時生產者持有鎖等待空槽。V(full)、消費者 V(empty) 方向相反。(index + 1) % N。