【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】

原子锁是多线程编程中的一个特色。然而,在平时的软件编写中,原子锁的使用并不是很多。这其中原因很多,我想主要有两个方面。第一,关于原子锁这方面的内容介绍的比较少;第二,人们在编程上面习惯于已有的方案,如果没有特别的需求,不过贸然修改已存在的代码。毕竟对很多人来说,不求有功,但求无过。保持当前代码的稳定性还是很重要的。  
    其实,早在《 多线程数据互斥》这篇博客中,我们就已经介绍过原子锁。本篇博客主要讨论的就是原子锁怎么使用。中间的一些用法只是我个人的一些经验,希望能够抛砖引玉,多听听大家的想法。

(1)查找函数中原子锁  

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

unsigned int count = 0;int find_data_process()
{if(/* data meets our standards */){EnterCriticalSection(&cs);count ++;LeaveCriticalSection(&cs);         }
}

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

unsigned int count = 0;int find_data_process()
{if(/* data meets our standards */){InterLockedIncrement(&count);}
}

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

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

void data_process()
{EnterCriticalSection(&cs);do_something();LeaveCriticalSection(&cs);
}

如果改成原子锁呢,会是什么样的呢?

unsigned int lock = 0;void data_process()
{while(1 == InterLockedCompareExchange(&lock, 1, 0));do_something();lock = 0;
}

这里用原子锁代替普通的系统锁,完成的功能其实是一样的。那么这中间有什么区别呢?其实,关键要看do_something要执行多久。打个比方来说,现在我们去买包子,但是买包子的人很多。那怎么办呢?有两个选择,如果卖包子的人手脚麻利,服务一个顾客只要10秒钟,那么即使前面排队的有50个人,我们只要等7、8分钟就可以,这点等的时间还是值得的;但是如果不幸这个卖包子的老板服务一个顾客要1分钟,那就悲催了,假使前面有50个人,那我们就要等50多分钟了。50分钟对我们来说可是不短的一个时间,我们完全可以利用这个时间去买点水果,交交水电费什么的,过了这个时间点再来买包子也不迟。

和上面的例子一样,忙等的方法就是原子锁,过一会再来的方法就是哪个传统的系统锁。用哪个,就看这个do_something的时间值不值得我们等待了。

多线程的那点儿事(之原子锁)相关推荐

  1. 多线程的那点儿事(之大结局)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 多线程一直是我比较喜欢的话题,当然也是很多朋友比较害怕的话题.喜欢它,因为它确实可以提高pc的 ...

  2. 多线程的那点儿事(之读写锁)

    在编写多线程的时候,有一种情况是十分常见的.那就是,有些公共数据修改的机会比较少.相比较改写,它们读的机会反而高的多.通常而言,在读的过程中,往往伴随着查找的操作,中间耗时很长.给这种代码段加锁,会极 ...

  3. 多线程的那点儿事(之数据同步)

    多线程创建其实十分简单,在windows系统下面有很多函数可以创建多线程,比如说_beginthread.我们就可以利用它为我们编写一段简单的多线程代码, [cpp] view plaincopy # ...

  4. 多线程的那点儿事(基础篇)

    多线程编程是现代软件技术中很重要的一个环节.要弄懂多线程,这就要牵涉到多进程?当然,要了解到多进程,就要涉及到操作系统.不过大家也不要紧张,听我慢慢道来.这其中的环节其实并不复杂. (1)单CPU下的 ...

  5. 多线程的那点儿事(之优先级反转)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 优先级反转对于编写应用层的人员来说不大会发生,但是对于操作系统的设计者来说确是一个逃不过去的问 ...

  6. 多线程的那点儿事(之多线程数据结构)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 要想编写多线程,那就要使用锁.而在软件编写中,数据结构是少不了的.所以,我们在编写多线程的时候 ...

  7. 多线程的那点儿事(之无锁队列)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 对于编写多线程的朋友来说,队列具有天生的互斥性.在队列里面,一个负责添加数据,一个负责处理数据 ...

  8. 多线程的那点儿事(之多线程调试)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 软件调试是我们软件开发过程中的重要一课.在前面,我们也讨论过程序调试,比如说这里.今天,我们还 ...

  9. 多线程的那点儿事(之避免死锁)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 预防死锁的注意事项: (1)在编写多线程程序之前,首先编写正确的程序,然后再移植到多线程 (2 ...

最新文章

  1. Java .net 心得_关于Java和.Net的一些感想
  2. Java并发:volatile内存可见性和指令重排
  3. 记阿里的一次壮烈牺牲
  4. spring源码构建以及模块划分和依赖
  5. python之路day03--数据类型分析,转换,索引切片,str常用操作方法
  6. 最简单的视频编码器:编译(libx264,libx265,libvpx)
  7. OpenCV中矩阵的归一化
  8. python 3d绘图kmeans_使用python绘制3d的图形
  9. python 奥数_Python 和 奥数 — 同余法求数值
  10. 浏览器趋势2016年9月:浏览器大战结束了吗?
  11. VScode设置为中文版
  12. php如何生成一年的日历表_PHP生成日历
  13. 商城APP软件开发要素有哪些
  14. 将两条类似的sql合并
  15. Activiti7-流程初体验
  16. z-index失效的几种情况,父标签position属性为relative的时候,详解
  17. 2055013-56-2,Ald-Ph-PEG2-amine TFA salt,CHO-Ph-PEG2-amine TFA
  18. 2020 最受 IT 公司欢迎的 30 款开源软件
  19. npm - 报错:found XXX vulnerabilities (XXX low, X moderate),run `npm audit fix` to fix them, or `npm au
  20. Monkey命令介绍

热门文章

  1. ServletContentLIstener接口演示ServletContext的启动和初始化
  2. 说说emit(上)基本操作
  3. MFC日志(2011.4.9)
  4. CDialog::OnOk()作用
  5. Tornado入门之旅
  6. 十一:贪心算法-寻找硬币
  7. oc61--block
  8. 听说本周五要进行一个小测试,公司对员工的考核
  9. 一周学会Mootools 1.4中文教程:(4)类型
  10. MyEclipse中将项目的编码从默认GBK改变为默认UTF-8