linux多线程之原子锁技术
原子锁是多线程编程中的一个特色。然而,在平时的软件编写中,原子锁的使用并不是很多。这其中原因很多,我想主要有两个方面。第一,关于原子锁这方面的内容介绍的比较少;第二,人们在编程上面习惯于已有的方案,如果没有特别的需求,不过贸然修改已存在的代码。毕竟对很多人来说,不求有功,但求无过。保持当前代码的稳定性还是很重要的。
其实,早在《 多线程数据互斥》这篇博客中,我们就已经介绍过原子锁。本篇博客主要讨论的就是原子锁怎么使用。中间的一些用法只是我个人的一些经验,希望能够抛砖引玉,多听听大家的想法。
(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 */){
EnterCriticalSection(&cs);
count ++;
LeaveCriticalSection(&cs);
}
}
我们看到代码中间使用到了锁,那么势必会涉及到系统调用和函数调度。所以,在执行效率上会大打折扣。那么如果使用原子锁呢?
- unsigned int count = 0;
- int find_data_process()
- {
- if(/* data meets our standards */){
- InterLockedIncrement(&count);
- }
- }
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);
- }
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;
- }
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的时间值不值得我们等待了。
linux多线程之原子锁技术相关推荐
- 【Linux】Linux多线程技术
Linux多线程概念 线程的概念 线程是计算机科学中的一个术语,是指运行中的程序的调度单位.一个线程指的是进程中一个单一顺序的控制流,也称为轻量进程.它是系统独立调度和分配的基本单位.同一进程中的多个 ...
- QEMU-KVM中的多线程压缩迁移技术
导读 目前的迁移技术,都是通过向QEMUFILE中直接写入裸内存数据来达到传送虚拟机的目的端,这种情况下,发送的数据量大,从而会导致更高的迁移时间(total time)和黑宕时间(downtime) ...
- linux多线程求和_谈一谈C++中的多线程(上)
本篇文章围绕以下几个问题展开: 何为进程?何为线程?两者有何区别? 何为并发?C++中如何解决并发问题?C++中多线程的语言实现? 同步互斥原理以及多进程和多线程中实现同步互斥的两种方法 Qt中的多线 ...
- 转:Linux网络IO并行化技术概览
转:http://codinginet.com/articles/view/201605-linux_net_parallel?simple=1&from=timeline&isapp ...
- 3、Linux多线程,线程同步(转)
3.Linux多线程,线程同步 5)线程私有数据 进程内的所有线程共享进程的数据空间,因此全局变量为所有线程所共有.但有时线程也需要保存自己的私有数据,这时可以创建线程私有数据(Thread-spec ...
- ZT 为什么pthread_cond_t要和pthread_mutex_t同时使用 || pthread/Linux多线程编程
为什么线程同步的时候pthread_cond_t要和pthread_mutex_t同时使用 (2009-10-27 11:07:23) 转载▼ 标签: 杂谈 分类: 计算机 举一个例子(http:// ...
- 《Linux多线程服务端编程:使用muduoC++网络库》学习笔记
文章目录 第1章 线程安全的对象生命期管理 1.1 当析构函数遇到多线程 1.1.1 线程安全的定义 1.1.3 线程安全实例 1.2 对象的创建很简单 1.3 销毁很难 1.4 线程安全的Obser ...
- Linux 多线程 ”一写多读” 模式下的无锁设计
缘起 双buffer "无锁" 设计 指针的切换 ptr 竞争条件的解决 指针访问丢失 延伸 结语 缘起 在linux多线程环境下对同一变量进行读写时,经常会遇到读写的原子性问题, ...
- 推荐《Linux 多线程服务器端编程》
赖勇浩(http://laiyonghao.com) 最近,有一位朋友因为工作需要,需要从网游的客户端编程转向服务器端编程,找我推荐一本书.我推荐了<Linux 多线程服务器端编程--使用 mu ...
- 【Linux练习生】Linux多线程
目录 Linux线程概念 线程的概念理解 vfork函数/pthread线程库 线程属性 线程的优点 线程的缺点 线程异常 线程用途 Linux进程VS线程 进程与线程的区别 进程的多个线程共享 Li ...
最新文章
- android线程栈默认大小,线程的默认最大堆栈大小 - Internet Information Services | Microsoft Docs...
- 阿里副总裁肖利华:数智化转型的7个关键词
- lumen认证中出现unauthorized._SpringBoot服务整合安全认证Security
- python条件控制语句要注意什么_浅析Python 条件控制语句
- PG13用pg_rman进行备份恢复
- 【JUC】第六章 Fork/Join 框架、CompletableFuture
- linux进程tss和ldt,x86体系下linux中的任务切换与TSS
- @ApiImplicitParam注解的dataType、paramType两个属性的区别?
- 虎牙面试官:String长度有限制吗?是多少?我:这太...
- 几个经常用到的字符串的截取(java)
- 《精通开关电源设计》笔记
- python攻击校园网_python爬虫 模拟登陆校园网-初级
- 怎么在服务器上显示u盘启动,电脑服务器怎么设置U盘启动
- IPAD2 恢复出厂设置
- 极简「Oauth2.0」微信网页授权教程
- 给虚拟机下载安装jdk,hadoop等(非常详细的步骤)
- java 多态判断非空_重拾JavaSE基础——多态及其实现方式
- 用python计算π值(模拟法)
- O - 鸣人和佐助(BFS)
- 痞子衡嵌入式:语音处理工具Jays-PySPEECH诞生记(3)- 音频显示实现(Matplotlib, NumPy1.15.0)...