[Linux] 信号量实现队列操作的同步与互斥(C++版)

/*===============================================================
*   Author: giturtle
*   描    述:实现线程安全的环形队列 (线性表实现的环形队列)
*	使用信号量实现队列操作的同步与互斥
================================================================*/
#include <iostream>
#include <vector>
#include <pthread.h>
#include <semaphore.h>

class RingQueue{
    public:
	RingQueue(int cap = 10):_queue(10), _capacity(cap),
	    _write_step(0), _read_step(0){
	    
	    sem_init(&_sem_data, 0, 0);
	    sem_init(&_sem_idle, 0, cap);
	    sem_init(&_sem_lock, 0, 1);
	}
	~RingQueue(){
	    sem_destroy(&_sem_data);
	    sem_destroy(&_sem_idle);
	    sem_destroy(&_sem_lock);
	}
	bool  QueuePush(int data){
	    ProductorWait();
	    QueueLock();
	    _queue[_write_step] = data;
	    _write_step = (_write_step + 1) % _capacity;
	    QueueUnLock();
	    ConsumerWakeUp();
	    return true;
	}
	bool  QueuePop(int *data){
	    ConsumerWait();
	    QueueLock();
	    *data = _queue[_read_step];
	    _read_step = (_read_step + 1) % _capacity;
	    QueueUnLock();
	    ProductorWakeUp();
	    return true;
	}
    private:
	void QueueLock(){
	    //通过计数判断是否有资源可操作 (计数-1 + 等待)
	    sem_wait(&_sem_lock);
	}
	void QueueUnLock(){
	    //计数+1 ,并唤醒等待
	    sem_post(&_sem_lock);
	}
	void ProductorWait(){
	    sem_wait(&_sem_idle);
	}
	void ProductorWakeUp(){
	    sem_post(&_sem_idle);
	}
	void ConsumerWait(){
	    sem_wait(&_sem_data);
	}
	void ConsumerWakeUp(){
	    sem_post(&_sem_data);
	}
    private:
	std::vector<int> _queue;
	int  _capacity;
	int  _write_step;
	int  _read_step;
	sem_t _sem_data;	//数据资源计数
	sem_t _sem_idle;	//空闲空间计数
	sem_t _sem_lock;	//实现互斥
};
void *thr_consumer(void *arg){
    RingQueue *q = (RingQueue*)arg;
    while(1) {
		int data;
		q->QueuePop(&data);
		std::cout<<"consumer thread get data:"<<data<<std::endl;
    }
    return NULL;
}
void *thr_productor(void *arg){
    RingQueue *q = (RingQueue*)arg;
    int i = 0;
    while(1) {
		q->QueuePush(i);
		std::cout<<"productor thread put data:"<<i<<std::endl;
		i++;
    }
    return NULL;
}
int main (int argc, char *argv[]){
    pthread_t ctid[4], ptid[4];
    int ret, i;
    RingQueue q;

    for (i = 0; i < 4; i++) {
		ret = pthread_create(&ctid[i], NULL, thr_consumer, (void*)&q);
		if (ret != 0) {
		    std::cout<<"thread create error\n";
		    return -1;
		}
    }
    for (i = 0; i < 4; i++) {
		ret = pthread_create(&ptid[i], NULL, thr_productor, (void*)&q);
		if (ret != 0) {
		    std::cout<<"thread create error\n";
		    return -1;
		}
    }
    for (i = 0; i < 4; i++) {
		pthread_join(ctid[i], NULL);
    }
    for (i = 0; i < 4; i++) {
		pthread_join(ptid[i], NULL);
    }
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

giturtle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值