多线程的那点儿事(之原子锁)解析 下载本文

内容发布更新时间 : 2024/5/14 4:27:01星期一 下面是文章的全部内容请认真阅读。

软件英才网 软件行业驰名招聘网站 有需要请联系我们

多线程的那点儿事(之原子锁) 原子锁是多线程编程中的一个特色。然而,在平时的软件编写中,原子锁的使用并不是很多。这其中原因很多,我想主要有两个方面。第一,关于原子锁这方面的内容介绍的比较少;第二,人们在编程上面习惯于已有的方案,如果没有特别的需求,不过贸然修改已存在的代码。毕竟对很多人来说,不求有功,但求无过。保持当前代码的稳定性还是很重要的。

其实,早在《多线程数据互斥》这篇博客中,我们就已经介绍过原子锁。本篇博客主要讨论的就是原子锁怎么使用。中间的一些用法只是我个人的一些经验,希望能够抛砖引玉,多听听大家的想法。

(1)查找函数中原子锁

在一些函数当中,有的时候我们需要对满足某种特性的数据进行查找。在传统的单核CPU 上,优化的空间比较有限。但是,现在多核CPU 已经成了主流配置。所以我们完全可以把这些查找工作分成几个子函数分在几个核上面并行运算。但是,这中间就会涉及到一个问题,那就是对公共数据的访问。传统的访问方式,应该是这样的, 1

unsigned int count = 0; 2 3

int find_data_process( 4 { 5

if (/* data meets our standards */{ 6 EnterCriticalSection(&cs; 7 count ++; 8

LeaveCriticalSection(&cs; 9 } 10 }

我们看到代码中间使用到了锁,那么势必会涉及到系统调用和函数调度。所以,在执行效率上会大打折扣。那么如果使用原子锁呢? 11 unsigned int count = 0;

12

13 int find_data_process( 14 {

15 if (/* data meets our standards */{ 16 InterLockedIncrement(&count; 17 } 18 }

有兴趣的朋友可以做这样一道题目,查看0~0xFFFFFFFF 上有多少数可以被3整除?大家也可以验证一下用原子锁代替临界区之后,代码的效率究竟可以提高多少。关于多核多线程的编程,朋友们可以参考《多线程基础篇》这篇博客。

软件英才网 软件行业驰名招聘网站

有需要请联系我们 (2)代码段中的原子锁

上面的范例只是介绍了统计功能中的原子锁。那么怎么用原子锁代替传统的系统锁呢?比如说,假设原来的数据访问是这样的,

19 void data_process( 20 {

21 EnterCriticalSection(&cs; 22 do_something(;

23 LeaveCriticalSection(&cs; 24 }

如果改成原子锁呢,会是什么样的呢? 25 unsigned int lock = 0; 26

27 void data_process( 28 {

29 while (1 == InterLockedCompareExchange(&lock, 1, 0; 30 do_something(; 31 lock = 0; 32 }

这里用原子锁代替普通的系统锁,完成的功能其实是一样的。那么这中间有什么区别呢?其实,关键要看do_something要执行多久。打个比方来说,现在我们去买包子,但是买包子的人很多。那怎么办呢?有两个选择,如果卖包子的人手脚