并发编程
文章平均质量分 86
无趣的人民艺术家
这个作者很懒,什么都没留下…
展开
-
进程、线程区别和联系
进程的状态 在上面,我们知道了进程有着「运行 - 暂停 - 运行」的活动规律。一般说来,一个进程并不是自始至终连续不停地运行的,它与并发执行中的其他进程的执行是相互制约的。 它有时处于运行状态,有时又由于某种原因而暂停运行处于等待状态,当使它暂停的原因消失后,它又进入准备运行状态。 所以,在一个进程的活动期间至少具备三种基本状态,即运行状态、就绪状态、阻塞状态。 进程的三种基本状态 上图中各个状态的意义: 运行状态(Runing):该时刻进程占用 CPU; 就绪状态(Ready):可运行,但因转载 2021-02-07 08:15:55 · 185 阅读 · 0 评论 -
互斥锁、自旋锁、悲观锁、乐观锁的应用场景
互斥锁与自旋锁:谁更轻松自如? 最底层的两种就是会「互斥锁和自旋锁」,有很多高级的锁都是基于它们实现的,你可以认为它们是各种锁的地基,所以我们必须清楚它俩之间的区别和应用。 加锁的目的就是保证共享资源在任意时间里,只有一个线程访问,这样就可以避免多线程导致共享数据错乱的问题。 当已经有一个线程加锁后,其他线程加锁则就会失败,互斥锁和自旋锁对于加锁失败后的处理方式是不一样的: 互斥锁加锁失败后,线程会释放 CPU,给其他线程; 自旋锁加锁失败后,线程会忙等待,直到它拿到锁; 互斥锁是一种「独.转载 2021-02-03 20:16:24 · 259 阅读 · 0 评论 -
无锁编程:c++11基于atomic实现共享读写锁
在多线程下,对临界资源的访问需要加锁,可以选择互斥锁这样的粗粒度锁或者基于CAS指令的原子语句实现互斥访问。关CAS等原子操作的概念参见下面的文章: 无锁队列的实现 以下代码利用atomic实现了一个轻量级的读写资源锁,保证有线程在读取时,写入线程阻塞,当写入线程执行时,所有的读取线程都被阻塞,并且可以根据需要通过构造函数参数设置读/写优先,且locck/unlock语句允许嵌套,相比利用互斥锁实现的读写锁,本锁更类似自旋锁 lock.readLock(); lock.readLock(); .原创 2021-02-02 21:23:14 · 1480 阅读 · 1 评论 -
内存顺序(Memory Order)问题
先理清几个前提: 1、CPU不能直接操作内存,CPU是通过 寄存器、缓存 等间接修改内存变量中的值 2、编译器在编译的时候,基于优化可能会对进行指令重排 3、运行期,为了提升执行效率,CPU内部可能也会进行指令重排 内存模型 对于大部分开发者而言,在写单线程程序,或者基于锁(Mutex)和信号量(Semaphore)之类编程框架提供的同步元语写多线程程序的时候,并不需要关心内存顺序的问题。 这是因为编译器和硬件架构保证了,虽然指令执行顺序可能跟开发者写的代码语句的顺序不一致,但是执行后的结果是一样原创 2021-01-28 21:46:37 · 1873 阅读 · 1 评论 -
单例模式和多线程
1、单例模式和多线程 不考虑多线程,单例可以代码如下: class Singleton { public: static Singleton* instance(); private: static Singleton* pInstance; }; Singleton* Singleton::pInstance = nullptr; Singleton* Singleton::instance() ...原创 2021-01-28 21:46:03 · 259 阅读 · 0 评论