线程安全与线程不安全

上一篇博客讲解使用readdir函数时遇到bug,其实就是由线程不安全产生的,所以想通过这篇博客来简单说明一下线程安全和线程不安全的问题。

线程安全 就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。 
  如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。 
  一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。 
线程不安全 就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据

线程安全问题都是由全局变量静态变量引起的。

若每个线程中对全局变量静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。

因此我们在使用系统函数时要注意线程安全问题;线程不安全主要分为以下四类:

第1类:不保护共享变量的函数,

函数中访问全局变量和堆。 
共享变量在多线程中是共享数据比如全局变量和堆,如果不保护共享变量,多线程时会出bug。 
可以通过同步机制来保护共享数据,比如加锁。

第2类:函数中分配,重新分配释放全局资源。

与上面第一点基本相同,通过加锁可解决

第3类:返回指向静态变量的指针的函数,函数中通过句柄和指针的不直接访问。

比如,我们要计算a,b两个变量的和,于是将a,b的指针传入某一个函数,然而此时可能有另一个线程改变了a,b的值,此时在函数中我们通过地址取到的两个数的值已经改变了,所以计算出的结果也就是错的了。 
又比如某些函数(如gethostbyname)将计算结果放在静态结构中,并返回一个指向这个结构的指针。在多线程中一个线程调用的结构可能被另一个线程覆盖。可以通过重写函数和加锁拷贝技术来消除。加锁拷贝技术指在每个位置对互斥锁加锁,调用线程不安全函数,动态的为结果分配存储器,拷贝函数返回的结构,然后解锁。

第4类:调用线程不安全函数的函数

猜你喜欢

转载自blog.csdn.net/cainiao000001/article/details/81148929
今日推荐