生产者消费者问题作为多线程多进程同步互斥的经典问题,值得思考。本文使用Linux系统调用,通过互斥锁和条件变量模拟生产者消费者问题。
代码语言:javascript复制#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
struct Node {
int _val;
Node *_next;
Node(int val, Node *next):_val(val), _next(next) {}
};
pthread_mutex_t mtx;
pthread_cond_t cond;
Node *head=NULL; // 全局变量 为消费者和生产者的互斥共享资源
void* func1(void *arg) {
while (1) {
pthread_mutex_lock(&mtx); // 涉及到访问临界区的访问都需要互斥锁保护
if (!head) { // head==NULL 缓冲区无内容可读
// 阻塞当前线程 并对mutex进行解锁操作
pthread_cond_wait(&cond, &mtx);
// 生产者通知消费者消费后 接触阻塞 并对mutex进行加锁操作
}
else {
// 删除头节点
Node *p = head;
head = p->_next;
printf("consumer: %lu thread, consume %dn", pthread_self(), p->_val);
delete p;
p = NULL;
}
pthread_mutex_unlock(&mtx);
}
return NULL;
}
void* func2(void *arg) {
while (1) {
pthread_mutex_lock(&mtx);
Node* p = new Node(rand()0, head);
head = p;
printf("producer: %lu thread, produce %dn", pthread_self(), p->_val);
pthread_mutex_unlock(&mtx);
pthread_cond_signal(&cond);// 通知消费者线程缓冲区现在又内容可以读
sleep(rand() % 3);
}
return NULL;
}
int main() {
srand(time(NULL));
pthread_mutex_init(&mtx, NULL);
pthread_cond_init(&cond, NULL);
pthread_t consumer, producer;
pthread_create(&consumer, NULL, func1, NULL);
pthread_create(&producer, NULL, func2, NULL);
pthread_join(consumer, NULL);
pthread_join(producer, NULL);
pthread_cond_destroy(&cond);
pthread_mutex_destroy(&mtx);
return 0;
}