当前位置: 首页 > wzjs >正文

网站排名优化外包公司长沙官网网站推广优化

网站排名优化外包公司,长沙官网网站推广优化,营销型网站建设定制网站建设,使用云主机做网站教程标题:[多线程]基于环形队列(RingQueue)的生产者-消费者模型 水墨不写bug 一、模型实现 接下来我们要实现一个基于环形队列(RingQueue)的生产者-消费者模型。该模型使用信号量和互斥锁来保证生产者和消费者之间的同步与…

标题:[多线程]基于环形队列(RingQueue)的生产者-消费者模型
@水墨不写bug


在这里插入图片描述


一、模型实现

接下来我们要实现一个基于环形队列(RingQueue)生产者-消费者模型。该模型使用信号量和互斥锁来保证生产者和消费者之间的同步与互斥操作。

#pragma once
#include <iostream>
#include <vector>
#include <pthread.h>
#include <semaphore.h>using std::cout;
using std::endl;// 基于环形队列的生产消费模型
// 与加锁不同,加锁要求对象rq内部内嵌一个锁,而两个信号量
// (sem_t _data_sem;  // 数据信号量
//     sem_t _spase_sem; // 空间信号量)
// 可以做到完美维护以下的四条规则:
/*1.生产者不会套消费者一圈2.消费者不超过生产者3.队列为空,消费者先消费4.队列为满,生产者先生产
*/template <typename T>
class RingQueue
{
private:// 信号量(计数器)自减——申请信号量void P(sem_t &psem){sem_wait(&psem);}// 信号量(计数器)自增——归还信号量void V(sem_t &vsem){sem_post(&vsem);}public:RingQueue(int maxcap): _ringqueue(maxcap), _maxcap(maxcap), _data_sem(), _space_sem(), _p_step(0), _c_step(0), _size(0){   // 初始化信号量sem_init(&_data_sem, 0, 0);sem_init(&_space_sem, 0, maxcap);// 初始化互斥锁pthread_mutex_init(&_p_mutex, nullptr);pthread_mutex_init(&_c_mutex, nullptr);}// 生产者向环形队列插入数据void Push(const T& in){// 申请空间信号量P(_space_sem);pthread_mutex_lock(&_p_mutex);_ringqueue[_p_step] = in;_p_step++;_p_step %= _maxcap;_size++;pthread_mutex_unlock(&_p_mutex);V(_data_sem);}// 消费者从环形队列拿出数据void Pop(T *out){// 申请数据信号量P(_data_sem);pthread_mutex_lock(&_c_mutex);*out = _ringqueue[_c_step];_c_step++;_c_step %= _maxcap;_size--;pthread_mutex_unlock(&_c_mutex);V(_space_sem);}~RingQueue(){// 销毁信号量sem_destroy(&_data_sem);sem_destroy(&_space_sem);}size_t GetSize(){return _size;}private:// 环形队列std::vector<T> _ringqueue;int _maxcap; // 最大数据个数sem_t _data_sem;  // 数据信号量sem_t _space_sem; // 空间信号量pthread_mutex_t _p_mutex; // 维护生产者之间关系的互斥锁pthread_mutex_t _c_mutex; // 维护消费者之间关系的互斥锁int _p_step; // 生产者位置int _c_step; // 消费者位置int _size; // 队列内数据个数
};

二、模型设计详解

1. 成员变量

  • std::vector<T> _ringqueue:环形队列,用于存储数据。
  • int _maxcap:队列的最大容量。
  • sem_t _data_semsem_t _space_sem:信号量,分别用于表示队列中的数据量和剩余空间量。(生产者和消费者关系的资源类型不同;生产者关心剩余空间资源,消费者关心剩余数据资源
  • pthread_mutex_t _p_mutexpthread_mutex_t _c_mutex:互斥锁,分别用于保护生产者和消费者的操作。
  • int _p_stepint _c_step:生产者和消费者在队列中的位置指针。
  • int _size:队列内数据的当前个数。

2. 构造函数

RingQueue(int maxcap): _ringqueue(maxcap), _maxcap(maxcap), _data_sem(), _space_sem(), _p_step(0), _c_step(0), _size(0)
{// 初始化信号量sem_init(&_data_sem, 0, 0);sem_init(&_space_sem, 0, maxcap);// 初始化互斥锁pthread_mutex_init(&_p_mutex, nullptr);pthread_mutex_init(&_c_mutex, nullptr);
}
  • 初始化环形队列的最大容量。
  • 初始化信号量,其中 _data_sem 的初始值为 0,表示初始时没有数据;_space_sem 的初始值为 maxcap,表示初始时队列可用空间为最大容量。
  • 初始化互斥锁 _p_mutex_c_mutex,分别用于维持生产者之间和消费者之间的互斥。

3. Push 函数

void Push(const T& in)
{// 申请空间信号量P(_space_sem);pthread_mutex_lock(&_p_mutex);_ringqueue[_p_step] = in;_p_step++;_p_step %= _maxcap;_size++;pthread_mutex_unlock(&_p_mutex);V(_data_sem);
}
  • P(_space_sem):生产者申请空间信号量,如果队列已满(信号量为0),则生产者阻塞等待。
  • pthread_mutex_lock(&_p_mutex):加锁保护生产者的操作。
  • 将数据插入到环形队列的当前位置 _p_step,然后更新 _p_step_size
  • pthread_mutex_unlock(&_p_mutex):解锁。
  • V(_data_sem):释放数据信号量,通知消费者有新数据可用。

4. Pop 函数

void Pop(T *out)
{// 申请数据信号量P(_data_sem);pthread_mutex_lock(&_c_mutex);*out = _ringqueue[_c_step];_c_step++;_c_step %= _maxcap;_size--;pthread_mutex_unlock(&_c_mutex);V(_space_sem);
}
  • P(_data_sem):消费者申请数据信号量,如果队列为空(信号量为0),则消费者阻塞等待。
  • pthread_mutex_lock(&_c_mutex):加锁保护消费者的操作。
  • 从环形队列的当前位置 _c_step 取出数据,然后更新 _c_step_size
  • pthread_mutex_unlock(&_c_mutex):解锁。
  • V(_space_sem):释放空间信号量,通知生产者有新的可用空间。

5. 析构函数

~RingQueue()
{// 销毁信号量sem_destroy(&_data_sem);sem_destroy(&_space_sem);
}
  • 销毁信号量,释放资源。

6. GetSize 函数

size_t GetSize()
{return _size;
}
  • 返回队列的当前大小。

三、模型总结

上述代码实现了一个基于环形队列的生产者-消费者模型,通过使用信号量来控制生产者和消费者之间的同步和互斥,通过互斥锁来保证生产者之间消费者之间的互斥。
信号量用于控制队列中的数据量和剩余空间量,互斥锁用于保护生产者和消费者的操作。通过这种方式,可以有效地避免资源竞争和死锁问题,实现了高效的生产和消费操作。

四、模型测试

以下给出了模型的测试逻辑代码,可以清晰的观察出单生产单消费,多生产多消费的情况:

#include "RingQueue.hpp"
#include <unistd.h>
#include <cstdlib>
void *Product(void *args)
{RingQueue<int> *rq = static_cast<RingQueue<int> *>(args);while (true){// 1.生产数据int tem = (rand() ^ pthread_self()) % 37;// 2.加入环形队列(访问临界资源)rq->Push(tem);cout << "Product num : " << tem << endl;sleep(1);// usleep(100000);}return nullptr;
}void *Consume(void *args)
{RingQueue<int> *rq = static_cast<RingQueue<int> *>(args);while (true){// 1.拿到数据(访问临界资源)int get;rq->Pop(&get);// 2.处理数据cout << "Consumer get :" << get << endl;//usleep(110000);}return nullptr;
}void test1()
{cout << "main thread started ---pid:" << getpid() << endl;srand((unsigned int)time(nullptr));RingQueue<int> *rq = new RingQueue<int>(10);// 创建线程pthread_t p, c;pthread_create(&p, nullptr, Product, (void *)rq);pthread_create(&c, nullptr, Consume, (void *)rq);while (1){cout << "队列内数据个数:" << rq->GetSize() << endl;sleep(1);}// 等待线程pthread_join(p, nullptr);pthread_join(c, nullptr);
}
void test2()
{cout << "main thread started ---pid:" << getpid() << endl;srand((unsigned int)time(nullptr));RingQueue<int> *rq = new RingQueue<int>(10);// 创建多个生产者消费者pthread_t p1, c1;pthread_t p2, c2;pthread_t p3, c3;pthread_t p4, c4;pthread_create(&p1, nullptr, Product, (void *)rq);pthread_create(&p2, nullptr, Product, (void *)rq);pthread_create(&p3, nullptr, Product, (void *)rq);pthread_create(&p4, nullptr, Product, (void *)rq);pthread_create(&c1, nullptr, Consume, (void *)rq);pthread_create(&c2, nullptr, Consume, (void *)rq);pthread_create(&c3, nullptr, Consume, (void *)rq);pthread_create(&c4, nullptr, Consume, (void *)rq);while (1){cout << "队列内数据个数:" << rq->GetSize() << endl;sleep(1);}// 等待线程pthread_join(p1, nullptr);pthread_join(p2, nullptr);pthread_join(p3, nullptr);pthread_join(p4, nullptr);pthread_join(c1, nullptr);pthread_join(c2, nullptr);pthread_join(c3, nullptr);pthread_join(c4, nullptr);
}int main()
{// 测试单生产单消费//  test1();// 测试多生产多消费test2();return 0;
}

完~
转载请注明出处


在这里插入图片描述

http://www.dtcms.com/wzjs/161019.html

相关文章:

  • aspmysql做网站产品网络营销
  • 做网站开发的公司昆明网站seo服务
  • 公司邮箱在哪里登录江东seo做关键词优化
  • 网站优化推广费用济南网站seo哪家公司好
  • 做网站怎么切图百度认证营销顾问
  • 咸阳免费做网站公司优化网站内容
  • wordpress挂靠主题seo网站排名推广
  • 天津免费做网站产品推广ppt
  • 防盗网站人做清洁今日十大头条新闻
  • 一诺千金 网站建设百度竞价冷门产品
  • 大连网站建设仟亿科技竞价推广外包托管
  • 重庆汉沙科技做网站怎么样嘉兴seo排名外包
  • 手机网站怎么导入微信朋友圈抖音关键词用户搜索排名靠前
  • 单位网站建设费用什么会计科目关键词排名哪里查
  • 苏州网站建设哪家好百度人工客服24小时电话
  • 个人如何建立公司网站发布平台有哪些
  • 做装修效果图的网站有哪些软件淘宝运营培训
  • 企业建设网站注意事项百度搜索资源平台官网
  • 成都有哪些做网站的自动引流推广app
  • 武汉网站建设全包营销软文范例大全100
  • 用花生壳做网站自媒体平台app下载
  • 制作网站作业关键时刻
  • 手机app应用开发公司当阳seo外包
  • 商城县建设局网站抖音广告推广
  • 加盟网站制作定制一份完整的活动策划方案
  • 政府网站建设认识不足网页是怎么制作的
  • 漳州网站建设喊博大科技自己怎么免费做网站
  • 网站建设套餐报价谷歌搜索引擎网址
  • 怎么做网站的bannergoogle谷歌搜索
  • 网站建设 定制三台网站seo