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

东莞塘厦做网站自助建站系统平台

东莞塘厦做网站,自助建站系统平台,马鞍山哪里做网站,建网站那个好对于生产者与消费者的数据处理的另一种好的解决方法是使用QWaitCondition类,允许线程在一定的条件下唤醒其他多个线程来共同处理。 一 定义公共变量 DataSize: 生产者生产数据的大小BufferSize: 也就是这个缓冲区的大小,每个单元是一个int,也有可能是一个链表,结构…

 

  • 对于生产者与消费者的数据处理的另一种好的解决方法是使用QWaitCondition类,允许线程在一定的条件下唤醒其他多个线程来共同处理。

一 定义公共变量

  • DataSize: 生产者生产数据的大小
  • BufferSize: 也就是这个缓冲区的大小,每个单元是一个int,也有可能是一个链表,结构体等等。
  • mutex: 为了保证多个线程操作同一块数据时的原子性操作
  • int numUsedBytes: 表示当前已经使用了多少个存储"单元"。
  • int rIndex = 0:由于使用多个消费者线程处理生产者数据,所以为了不重复读取,设置全局变量rIndex用于标识当前读取到缓冲区的位置。
const int DataSize=1000;
const int BufferSize=80;
int buffer[BufferSize];
QWaitCondition bufferEmpty;
QWaitCondition bufferFull;
QMutex mutex;
int numUsedBytes = 0;
int index = 0;

二 生产者

  • 同样的继承QThread,在run函数中完成生产者的工作。
  • 首先进入for循环就必须对整个for循环中的操作进行加锁。只需要记住如果有一个变量在生产者和消费者线程中都会被改变,那么这个变量存在的地方就必须加锁。比如这里的numUseBytes;
  • if(numUsedBytes == BufferSize) 如果已经使用的单元等于当前缓冲区单元数,那么就必须等待消费者处理
  • bufferEmpty.wait(&mutex):等待“缓冲区有空位”,也就是当缓冲区写满时,等待消费者线程读取(处理)缓冲区,wait()函数会将互斥量mutex在此解锁并且QWaitComdition在此等待。这个函数的原型如下:
  1. 首先传入的参数是一个被锁定的互斥量,如果传入时的互斥量不是被锁定的,或者出现递归锁的情况,那么wait会立刻返回。
  2. 参数2传入的是等待时间
  3. 首先我们要知道的是在这QWaitComdition在这里等待的结束条件。如果在其他线程调用了QWaitComdition的方法wakeOne或者wakeAll,那么这个函数就会返回true
  4. 由于第二个参数默认是永不超时,但是当我们设置了超时,并且在超时后,并没有被唤醒,那么就会返回false,
  5. 无论这个返回的是true还是false,再返回前QWaitComdition都会将QMutex重新设置为锁定状态。
  • buffer[i%BufferSize]= numUsedBytes:生产者向缓冲区写入数据
  •  numUsedBytes++:让使用过的缓冲单元数量加一
  •  bufferFull.wakeAll():唤醒所有等待QWaitCondition的线程。
  • 对于wakeOne是随机唤醒一个等待线程,而wakeAll则是唤醒所有等待线程。

bool QWaitCondition::wait(QMutex *mutex,unsigned long time = ULONG_MAX);

void Producer::run()
{for(int i=0;i<DataSize;i++){mutex.lock();if(numUsedBytes == BufferSize){bufferEmpty.wait(&mutex);}buffer[i%BufferSize] = numUsedBytes;numUsedBytes++;mutex.unlock();bufferFull.wakeAll();}
}

三 消费者

  • 首先我们判断当可用的数据为0时,就需要等待生产者来激活QWaitCondition
  • 当缓冲单元有可用的数据时,我们读取当前缓冲单元中的数据,并对这个index下标进行处理。
  • 最后我们徐亚将numUsedBytes减一,也就是缓冲区已经用过的数据-1。
  • bufferEmpty.wakAll:激活所有等待缓冲区有空位的条件线程
void Consumer::run()
{Q_FOREVER{mutex.lock();while (numUsedBytes == 0) { // 确保缓冲区不为空bufferFull.wait(&mutex, QDeadlineTimer::Forever);}qDebug()<<currentThreadId()<<index<<buffer[index];index = (++index)%BufferSize;--numUsedBytes;mutex.unlock();bufferEmpty.wakeAll();}
}

四 调用

    Producer producer;Consumer consumer;Consumer consumerB;producer.start();consumer.start();consumerB.start();producer.wait();consumer.wait();consumerB.wait();

五 对qt书籍上示例的优化

5.1 wake的时机

  • 在这里我把wake的时机放到了解锁之后,也就是先解锁后wake
  • 虽然二者的顺序无关紧要,但是如果在这个场景下我们将wake放在解锁的后面,对于消费者而言,可能处理速度上就会快一点,因为很多情况下可能并没有在wait等待
  • 需要wakeall是立即激活所有等待的线程,此时会重新获得锁也就是lock(),但是也是会等待锁被释放后才能获取到。

5.2 消费者的线程同步问题

  • 我们需要在判断是否有可读的数据时也加上while循环判断来进行wait
  • 否则就会导致一种场景:当可用单元为0时,此时两个消费者都在wait,当生产者激活(将可以单元加1)后,比如消费者A先获取到锁,对其数据进行处理,此时就会导致一个问题,处理结束后可用单元numUsedByte变为了0,紧接着进行unlock解锁,但是此时消费者B就会紧接着获取到锁,因为它在上次numUsedByte等于0是也在等待获取锁。此时就会将这个numUsedByte变为-1,此时数据的处理就会乱套。

 

http://www.tj-hxxt.cn/news/17721.html

相关文章:

  • 国外被动收入网站做的好的竞价托管一般要多少钱
  • 网站开发需要懂哪些北京优化网站公司
  • 新洲建设投标网站可以直接进入的舆情网站
  • 网站建设类型报价表seo关键词排名公司
  • 做网站赚钱 优帮云网络推广的概念
  • 抖音网站开发seo外包公司兴田德润
  • 官方网站的域名seo专业术语
  • wordpress 统计文章数量windows优化大师官方免费
  • 大学个人网站期末作业海外推广营销平台
  • 动漫网站模板设计图免费写文章的软件
  • soho个人可以建网站吗新榜数据平台
  • dedecms大气金融企业网站模板长春网站制作企业
  • 微 网站北京排名seo
  • 行业平台网站建设搜索引擎营销与seo优化
  • 在婚恋网站上做红娘怎么样百度收录查询工具官网
  • 贵州网站建设公司培训机构如何招生营销
  • 制作logo免费网站南京网络营销服务
  • 做网站会被捉吗中国十大热门网站排名
  • 怎么做别人可以上的网站自学seo能找到工作吗
  • 汽车网站建设网络推广的常用方法
  • 渭南网站建设网站建设电商网站商品页的优化目标是什么
  • 山东青岛网站建设公司排名外贸网站模板
  • 企业网站托管常见问题sem竞价托管公司
  • 嘉鱼网站建设公司百度识图网站
  • 我帮诈骗团伙做诈骗网站获利媒体:北京不再公布各区疫情数据
  • 网页设计实训总结报告大全seo矩阵培训
  • 如何将网站指向404疫情最新消息今天
  • 广州科技网站建设线上推广软件
  • 建设部网站诚信平台免费推广网站大全集合
  • wordpress页面立体效果宁波seo关键词如何优化