在Linux多线程编程中,线程间的同步与通信是至关重要的课题。本文将带你彻底搞懂POSIX信号量,并基于环形队列实现经典的生产者消费者模型,即使你是初学者也能轻松跟上。
POSIX信号量是一种用于线程/进程同步的机制,它本质上是一个计数器,支持两种原子操作:sem_wait()(P操作)和sem_post()(V操作)。在Linux系统中,通过sem_t类型及相关函数(sem_init, sem_destroy, sem_wait, sem_post)来操作。信号量常用于解决生产者消费者问题,控制对共享资源的访问。
生产者消费者模型描述了两类线程(生产者和消费者)共享一个固定大小的缓冲区。生产者向缓冲区放入数据,消费者从中取出数据。关键是要保证:缓冲区满时生产者等待,缓冲区空时消费者等待。环形队列(Circular Queue)作为缓冲区非常高效,它利用数组和两个指针(读写指针)实现循环存储,避免了数据搬移。
图:环形队列,写指针追赶读指针
我们可以用两个POSIX信号量来同步生产者和消费者:
sem_t blank_sem:空闲格子数(初始为队列大小N)int data_sem:已填充数据格子数(初始为0)#define N 10 // 环形队列大小typedef struct { int buf[N]; // 数据缓冲区 int in; // 生产者写入位置 int out; // 消费者读取位置 sem_t blank_sem; // 空闲格子信号量 sem_t data_sem; // 数据格子信号量} ring_queue_t; void queue_init(ring_queue_t *q) { q->in = q->out = 0; sem_init(&q->blank_sem, 0, N); // 初始有N个空格子 sem_init(&q->data_sem, 0, 0); // 初始0个数据格子} void producer(ring_queue_t *q, int item) { sem_wait(&q->blank_sem); // 等待空闲格子 // 此处可加互斥锁(多生产者时) q->buf[q->in] = item; q->in = (q->in + 1) % N; // 解锁 sem_post(&q->data_sem); // 增加数据格子} int consumer(ring_queue_t *q) { sem_wait(&q->data_sem); // 等待有数据 // 可加互斥锁(多消费者时) int item = q->buf[q->out]; q->out = (q->out + 1) % N; // 解锁 sem_post(&q->blank_sem); // 释放一个空格子 return item;} 通过信号量的计数,我们完美实现了环形队列的同步:当队列满时blank_sem为0,生产者阻塞;当队列空时data_sem为0,消费者阻塞。这便是生产者消费者模型的核心思想。
下面给出一个简单的测试程序,创建两个线程分别生产/消费整数:
#include #include #include #include #define N 5ring_queue_t q;void* prod_thread(void* arg) { for(int i = 0; i < 10; i++) { producer(&q, i); printf("Produced %d", i); sleep(1); } return NULL;}void* cons_thread(void* arg) { for(int i = 0; i < 10; i++) { int val = consumer(&q); printf("Consumed %d", val); sleep(2); } return NULL;}int main() { queue_init(&q); pthread_t tid1, tid2; pthread_create(&tid1, NULL, prod_thread, NULL); pthread_create(&tid2, NULL, cons_thread, NULL); pthread_join(tid1, NULL); pthread_join(tid2, NULL); sem_destroy(&q.blank_sem); sem_destroy(&q.data_sem); return 0;} 运行结果将展示生产者与消费者交替操作,且不会出现数据覆盖或重复读取。这个例子清晰地展示了Linux多线程下如何利用POSIX信号量构建高效的环形队列模型。
sem_init的pshared参数为0表示线程间共享。in/out时加互斥锁,防止竞态条件。希望通过本文,你已掌握Linux多线程编程中POSIX信号量的使用,并能独立实现基于环形队列的生产者消费者模型。动手试试吧!
本文由主机测评网于2026-03-08发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://vpshk.cn/20260329486.html