首页 > 解决方案 > 锁之前/之后的代码总是串行执行?

问题描述

CodeBlockA;

Lock;
CodeBlockB;
Unlock;

CodeBlockC

代码块可能包含很多代码,以它为一个单元即可。

CodeBlockA CodeBlockB CodeBlockC 是否总是串行执行?lock 是如何实现的?</p>

标签: cmutexcritical-sectionspinlocklockless

解决方案


现在,我不知道其他系统,但在 linux 上是这样的:

线程

在 NPTL 中,线程同步原语(互斥锁、线程连接等)是使用 Linux futex(2) 系统调用实现的。

futex

当执行请求阻塞线程的 futex 操作时,仅当 futex 字具有调用线程提供的值(作为 futex() 调用的参数之一)作为 futex 字的预期值时,内核才会阻塞. futex 字的值的加载、该值与预期值的比较以及实际的阻塞将自动发生,并且将相对于其他线程在同一个 futex 字上执行的并发操作完全排序。因此,futex 字用于连接用户空间的同步和内核的阻塞实现。类似于可能更改共享内存的原子比较和交换操作,通过 futex 阻塞是原子比较和阻塞操作。

C - mtx_lock

在同一个互斥体上对 mtx_unlock 的先前调用与此操作同步,并且任何给定互斥体上的所有锁定/解锁操作形成一个单一的总顺序(类似于原子的修改顺序)

C 标准 n2596

7.26.4 互斥函数

为了确定数据竞争的存在,锁定和解锁操作表现为原子操作。对特定互斥体的所有锁定和解锁操作都以特定的总顺序发生。

注意这个总顺序可以看作是互斥体的修改顺序。


推荐阅读