线程安全

来源:互联网 发布:上海政府数据开放平台 编辑:程序博客网 时间:2024/05/30 05:09

转自线程安全


线程安全是编程中的术语,指某个函数 (计算机科学)、函数库在多线程环境中被调用时,能够正确地处理各个线程的局部变量,使程序功能正确完成。

一般来说,线程安全的函数应该为每个调用它的线程分配专门的空间,来储存需要单独保存的状态(如果需要的话),不依赖于“线程惯性”,把多个线程共享的变量正确对待(如,通知编译器该变量为“易失(volatile)”型,阻止其进行一些不恰当的优化),而且,线程安全的函数一般不应该修改全局对象。

很多C库代码(比如某些strtok的实现,它将“多次调用中需要保持不变的状态”储存在静态变量中,导致不恰当的共享)不是线程安全的,在多线程环境中调用这些函数时,要进行特别的预防措施,或者寻找别的替代方案。

例子

在下面这段代码中,函数increment_counter是线程安全的,但不是可重入的。

#include <pthread.h> int increment_counter (){static int counter = 0;static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&mutex); // only allow one thread to increment at a time++counter;// store value before any other threads increment it furtherint result = counter; pthread_mutex_unlock(&mutex); return result;}

上面的代码中,函数increment_counter可以在多个线程中被调用,因为有一个互斥锁mutex来同步对共享变量counter的访问。但是如果这个函数用在可重入的中断处理程序中,如果在pthread_mutex_lock(&mutex)和pthread_mutex_unlock(&mutex)之间产生另一个调用函数increment_counter的中断,则会第二次执行此函数,此时由于mutex已被lock,函数会在pthread_mutex_lock(&mutex)处阻塞,并且由于mutex没有机会被unlock,阻塞会永远持续下去。

使用c++11中的atomics,可使此函数即线程安全又可重入。

#include <atomic> int increment_counter (){static std::atomic<int> counter(0); // increment is guaranteed to be done atomicallyint result = ++counter; return result;}


0 0