中国人做外贸网站都卖什么,自己做网站上传相册,个人网页制作成品代码五个页面,长沙网站开发微联前言#xff1a;
生产者消费者模型是老生常谈的话题#xff0c;实现手段也是各种各样#xff0c;不同的手段的 运行效率也是天壤之别。代码简洁度#xff0c;数据安全性#xff0c;运行稳定性#xff0c;运行性能等等要素很难做到兼顾。 最基本的模型 - 大粒度锁 忙…前言
生产者消费者模型是老生常谈的话题实现手段也是各种各样不同的手段的 运行效率也是天壤之别。代码简洁度数据安全性运行稳定性运行性能等等要素很难做到兼顾。 最基本的模型 - 大粒度锁 忙等循环check / busy check
组件
mutex
代码
#include thread
#include mutex
#include list
#include unistd.h
#include stdio.hstd::listlong FIFO;
std::mutex lock;
long consumer_v -1;
long producer_v 9999999;void consumer(){static long times0;while(consumer_v!0){std::unique_lockstd::mutex ul(lock);if(!FIFO.empty()){consumer_v std::move(FIFO.front());FIFO.pop_front();times;}else{//usleep(1); //降低轮询次数以节省cputimes;}}printf(consumer times : %ld\n , times);
}void producer(){static long times0;while(producer_v--!0){std::unique_lockstd::mutex ul(lock);FIFO.push_back(producer_v);times;}printf(producer times : %ld\n , times);
}int main()
{std::thread cons(consumer);std::thread prod(producer);cons.join();prod.join();
}
以上代码中cpu通常会达到200%原因是 consumer 中需要判断FIFO 中是否有数据如果没有数据要再次加锁和判断因此这数据 busy check 代码结构这个过程会非常耗费 cpu 。 通过top命令查看 %CPU 200.0 可以通过usleep来降低轮询频率从而降低cpu 但是弊端代码就是执行时间会变长。 $ time ./1 producer times : 9999999 consumer times : 10002394 real 0m16.661s user 0m19.614s sys 0m13.541s 每次运行上述代码都会发现输出结果中consumer times 的值会有很大波动有时比 producer times 大几百有时大几千这些就是无用轮询的次数。
优缺点
优点代码简洁易懂方便阅读和修改逻辑清晰。
缺点
1cpu和运行效率无法兼得要么cpu忙这往往是绝对无法接收的
2要么运行效率无法得到保障sleep间隔长了则效率低短了则cpu忙
3竞争数据的加锁粒度大一次性把整个list都锁住了。不过这一点不是太大的问题而且优化起来难度较高一般属于无锁编程范畴。不属于严重的缺点。 改善CPU的模型 - 大粒度锁 休眠唤醒
为了改善 cpu 忙等问题可以使用休眠唤醒机制。把唤醒工作交给内核达到在不进行 busy check 的前提下还可以来提升等待线程的响应效率的目的。
组件
conditional variable / semaphore 其他
当我们锁住列表的时候释放锁的时机要控制好建议通过 std::move 把需要处理的数据从 FIFO 中拿出来或者 通过拷贝的方式拷贝拿出来然后立刻就把锁释放掉这样不会影响其他线程加锁。不可以在锁住状态中执行耗时操作除非你有充分的理由或者知道自己在干啥。