![](https://img-blog.csdnimg.cn/20201014180756925.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C++并发编程
文章平均质量分 72
explore翔
安徽某985小硕,记录日常学习生活,欢迎大家交流指教。
展开
-
高级线程管理-线程池
线程池就提供了这样的功能,提交到线程池中的任务将并发执行,提交的任务将会挂在任务队列上。对于IO密集任务(网络,硬盘,web),IO占比越多,线程应该越多,因为阻塞时间越多,就需要切换线程。当然还可以动态,如果活动线程大于80%,就新增线程。最好的并发就是不共享资源,所以为每个线程设计一个队列,里面放一类任务,这样,如果有全局变量啥的,他只会在这个线程处理,不是跨线程的变量,访问任务时不需要加锁。最好设计一个管理线程,这时线程容器可以用map来存储,id和线程本身,这样删除线程很快,不需要在数组里面找。原创 2023-01-13 20:19:41 · 311 阅读 · 0 评论 -
C++原子类型操作
(实际上,不推荐用while实现自旋锁,可以用CPU提供的PAUSE指令,通过休眠一定的时钟周期,减少流水线上并行的load数量(读操作),减少流水线重排消耗的时间(25倍的差距))(自旋锁和互斥锁的区别:互斥锁就是当加锁失败后,线程让出CPU,被阻塞,锁被释放后,再唤醒它。那么如果锁住的代码执行时间极短,远小于线程切换的时间(而且线程的私有数据已经在cache预热了,一进一出,cache的命中率很低),那么就不如自旋等待。但是,由于x86_64是强顺序内存模型,为了保险,最好不要用弱顺序的。原创 2023-01-07 20:31:24 · 551 阅读 · 0 评论 -
同步并发操作
(std::future提供了一个访问异步操作结果的机制,它和线程是一个级别的属于低层次的对象,在它之上高一层的是std::packaged_task和std::promise,他们内部都有future以便访问异步操作结果,std::packaged_task包装的是一个异步操作,而std::promise包装的是一个值,都是为了方便异步操作的。要解决该问题,就必须让生产者在缓冲区满时休眠(要么干脆就放弃数据),等到下次消费者消耗缓冲区中的数据的时候,生产者才能被唤醒,开始往缓冲区添加数据。原创 2023-01-05 21:49:49 · 323 阅读 · 0 评论 -
线程间共享数据
互斥量和要保护的数据,在类中都需要定义为private成员,这会让访问数据的代码变的清晰,并且容易看出在什么时候对互斥量上锁。这是面向对象设计的准则:将其放在一个类中,就可让他们联系在一起,也可对类的功能进行封装,并进行数据保护。在C++ STL模板库中,已经实现stack功能,但是std::stack却不是线程安全的,因为stack成员函数存在恶性条件的数据竞争,导致多线程环境下,数据出现错误。,其会在构造的时候提供已锁的互斥量,并在析构的时候进行解锁,从而保证了一个已锁的互斥量总是会被正确的解锁。原创 2023-01-04 22:00:32 · 319 阅读 · 0 评论 -
C++11线程管理
阻塞调用者(caller)所在的线程直至被join的std::thread对象标识的线程执行结束。(detach会使线程对象th1失去对该线程的控制权,有可能导致主程序退出时该线程还没执行完,所以一般不用detach,除非它是很重要的后台线程)detach:将当前线程对象所代表的执行实例与该线程对象分离,使得线程的执行可以单独进行。一旦线程执行完毕,它所分配的资源将会被释放。向std::thread构造函数中的可调用对象,或函数传递一个参数很简单,默认参数要拷贝到线程独立内存中,即使参数是引用的形式。原创 2023-01-03 18:39:44 · 262 阅读 · 0 评论