博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
什么代码才是线程安全的
阅读量:6814 次
发布时间:2019-06-26

本文共 2112 字,大约阅读时间需要 7 分钟。

对于多线程编程,很多人概念不清,写代码的时候要么是处处加锁,影响性能不说,还容易莫名其妙的死锁,还有人对多线程敬而远之。
所以学习多线程编程最重要的不是学习API,而是理解什么才是多线程安全的代码
从例子说起
#include 
<
windows.h
>
#include 
<
process.h
>
long
 global1 
=
 
0
;
volatile
 
long
 global2 
=
 
0
;
class
 MyClass
{
public
:
    MyClass() : m(
0
)
    {
        
++
m;
    }
    
int
 fun(
int
 v)
    {
        
return
 m
+
v; 
//
-----------9
    }
    
void
 
set
(
int
 v)
    {
        m 
=
 v;   
//
-------------10
    }
    
int
 m;
};
MyClass global_object; 
//
-------------8
unsigned 
int
 __stdcall thread_fun1(
void
 
*
param)
{
    
static
 
int
 static2 
=
 
0
;
    
static
 MyClass static_object; 
//
--------6
    
int
 local1 
=
 
0
;
    
    
++
local1;     
//
-------1
    
++
static2;    
//
-------2
    
++
global1;    
//
-------3
    
++
global2;    
//
-------4
    InterlockedIncrement(
&
global1); 
//
--------5
    local1 
=
 global_object.fun(local1); 
//
----------7
    global_object.
set
(local1); 
//
---------------11
    
return
 
0
;
}
unsigned 
int
 __stdcall thread_fun2(
void
 
*
param)
{
    
++
global1;    
//
-------3
    
++
global2;    
//
-------4
    InterlockedIncrement(
&
global1); 
//
--------5
    global_object.
set
(
1
); 
//
-----------11
    
return
 
0
;
}
int
 main()
{
    HANDLE thread1 
=
 (HANDLE)_beginthreadex(
0
,
0
,
&
thread_fun1,
0
,
0
,
0
); 
//
thread 1
    HANDLE thread2 
=
 (HANDLE)_beginthreadex(
0
,
0
,
&
thread_fun1,
0
,
0
,
0
); 
//
thread 2
    HANDLE thread3 
=
 (HANDLE)_beginthreadex(
0
,
0
,
&
thread_fun2,
0
,
0
,
0
); 
//
thread 3
    
    WaitForSingleObject(thread1,INFINITE);
    WaitForSingleObject(thread2,INFINITE);
    WaitForSingleObject(thread3,INFINITE);
    
    
return
 
0
;
}
1.局部变量局部使用是安全的
为什么?因为每个thread 都有自己的运行堆栈,而局部变量是生存在堆栈中,大家不干扰。
所以代码1
int local1;
++local1;
是安全的
2.全局原生变量多线程读写是不安全的
全局变量是在堆(heap)中
long global1 = 0;
++global2;
++这个操作其实分为两部,一个是读,另外一个是写
 mov         ecx,global
 add         ecx,1
 mov         global,ecx
所以代码3处是不安全的
3.函数静态变量多线程读写也是不安全的
道理同2
所以代码2处也是不安全的
4.volatile能保证全局整形变量是多线程安全的么
不能。
volatile仅仅是告诫compiler不要对这个变量作优化,每次都要从memory取数值,而不是从register
所以代码4也不是安全
5.InterlockedIncrement保证整型变量自增的原子性
所以代码5是安全的
6.function static object的初始化是多线程安全的么
不是。
著名的Meyer Singleton其实不是线程安全的
Object & getInstance()
     static Object o;
     return o;
}
可能会造成多次初始化对象
所以代码6处是不安全的
7.在32机器上,4字节整形一次assign是原子的
比如
i =10; //thread1
i=4; //thread2
不会导致i的值处于未知状态,要么是10要么是4
写好多线程安全的法宝就是封装,使数据有保护的被访问到
安全性:
局部变量>成员变量>全局变量

 

 

from:

转载地址:http://mxmwl.baihongyu.com/

你可能感兴趣的文章
SDUT OJ[3109] 买买买 背包 dp
查看>>
SQL 注入防御方法总结
查看>>
fiddler使用
查看>>
Java之观察者模式
查看>>
kqueue epoll 边界触发模式的网络编程模型
查看>>
每天一道算法题(16)——翻转链表
查看>>
my vim IDE 编辑器的配置
查看>>
Jenkins持续集成学习-搭建jenkins问题汇总
查看>>
Print 与Debug.Log的区别
查看>>
Servlet各种接口和类
查看>>
input光标高度问题
查看>>
基础命令集合
查看>>
【转】poj pku 线段树题目20道汇总+简要算法+分类+难度
查看>>
python不同目录下的调用
查看>>
关于命令ride.py打不开RF,而是打开pycharm编辑器问题解决思路
查看>>
Codebook model 视频抠像 xp sp3 + vs2005 + OpenCV 2.3.1
查看>>
ffmpeg-20160714-git-bin.7z
查看>>
ListView下拉刷新实现(类似陌陌的箭头转动)
查看>>
[Android编程心得] Camera(OpenCV)自动对焦和触摸对焦的实现
查看>>
Android apk的安装、卸载、更新升级(通过Eclipse实现静默安装)
查看>>