如何保证线程安全?

  • Post author:
  • Post category:其他




相信大家在面试的时候都有被问到过这个问题。如何保证线程安全?

线程安全,即在多线程的环境下,可访问的全局变量和堆数据随随时都可能被其他的线程改变。因此多线程程序在并发时数据的一致性变得非常重要。



原子操作

即代码经过编译后变成汇编文件,每行代码都翻译成汇编直连,我们把一行代码对应一条汇编指令的操作,称之为原子操作。因为无论如何,单条指令的执行是不会被打断的。




当我们需要保证一个复杂的数据结构更改时,原子操作就会力不从心了。这里就需要使用更加通用的手段了:锁。

为了避免多个线程同时读写一个数据而产生不可预料的后果,我们需要将各个线程对同一个数据的访问同步,所谓同步,即是指在一个线程访问数据未结束的时候,其他线程不得对同一个数据进行访问。

锁有很多种类型,用于使用不同的场景。

如互斥锁,自旋锁,读写锁,临界区,条件变量等



函数的可重入性

一个函数被重入,表示这个函数没有执行完成,由于外部因素或者内部调用,有一次执行该函数。

一个函数被冲入只有两种情况:

  1. 多个线程同时执行这个函数
  2. 函数递归

一个函数要成为可重入的,必须具有以下几个特点:

1. 不适用任何静态或者全局的非const变量

2. 不返回任何静态或全局的非const变量的指针

3. 仅依赖调用方提供的参数

4. 不依赖任何单个资源的锁

5. 不调用任何不可重入的函数



过度优化

编译器为了提高速率将一个变量缓存到寄存器中,而不将变量的值写回内存中。使用volatile来修饰该变量,可以阻止该行为。

编译器有可能会调整volatile变量的指令顺序。使用barrier指令来阻止换顺序。



版权声明:本文为qq_44111565原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。