可重入函数与与线程安全与volatile

引子:单线程程序只有一个控制流。不需要考虑静态或全局变量被同时访问或并发访问,但是多线程程序必须考虑并发访问一个资源。为了保证资源的完整性,为多线程程序写的代码必须是可重入的和线程安全的。

1.0 定义:

           线程安全的(Thread-Safe):如果一个函数在同一时刻可以被多个线程安全地调用,就称该函数是线程安全的。线程安全函数解决多个线程调用函数时访问共享资源的冲突问题。

          可重入(Reentrant)函数可以由多于一个线程并发使用,而不必担心数据发生改变,可重入函数可以在任意时刻被中断,稍后再继续运行,而结果总是唯一的。可重入性解决函数运行结果的确定性和可重复性

         volatile   避免编译器对变量做冗余装载和存储删去的优化,即告诉编译器每次操作被volatile修饰的变量都直接从内存读取或者写回内存而不是只操作寄存器里的备份.(全局共享的数据一般建议使用volatile关键字保护)

2.0 两者之间的关系:

  1. 一个函数对于多个线程是可重入的,则这个函数是线程安全的。
  2. 一个函数是线程安全的,但并不一定是可重入的
  3. 可重入性要强于线程安全性。

两者的侧重点不一样:

  1. 线程安全强调的是函数并发或者异步使用不会相互干扰,如果函数使用共享资源(静态变量/全局变量),则需要加锁保证互斥访问
  2. 可重入强调的是函数并发或者异步使用结果总是唯一的,函数不能使用共享资源

线程安全函数,满足以下两点之一:

  1. 不使用静态或全局数据等共享资源
  2.  使用了共享资源,但加锁保护

可重入的函数需要做到如下三点

  1. 不在函数内部使用静态或全局数据
  2. 不返回静态或全局数据,所有数据都由函数的调用者提供。
  3. 不调用不可重入函数

使用volatile的情况有

  1. 内存映射硬件
  2. 中断服务程序/信号处理程序中会访问到的全局变量  
  3. 多进程应用中的共享内存和多线程应用中被几个线程共享的变量

命题:   全局A赋值给C

赋值过程:    赋值过程  先A赋值给B ,再B赋值给C  

主进程:先A赋值给B    B = A  ;   在这产生中断

中断:   调用到A   ,并A  = D,退出中断。

主进程: 再B赋值给C,  B = C。

猜你喜欢

转载自blog.csdn.net/h490516509/article/details/85327947