fbpx
维基百科

线程安全

线程安全程式設計中的术语,指某个函数函数库多執行緒环境中被调用时,能够正确地处理多个執行緒之间的公用變數,使程序功能正确完成。

假設有間銀行只有 1000 元,而兩個人同時提領 1000 元時就可能會拿到總計 2000 元的金額。為了避免這個問題,該間銀行提款時應該使用互斥鎖,即意味著針對同一個資源處理時,前一個人提領交易完成後才處理下一筆交易。但這種手法會使得效能降低。

一般来说,线程安全的函数应该为每个调用它的线程分配专门的空间,来储存需要单独保存的状态(如果需要的话),不依赖于“线程惯性”,把多个线程共享的变量正确对待(如,通知编译器该變數为“易失(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 further  int 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,阻塞会永远持续下去。简言之,问题在于 pthread 的 mutex 不可重入。

解决办法是设定 PTHREAD_MUTEX_RECURSIVE 属性。然而对于给出的问题而言,专门使用一个 mutex 来保护一次简单的增量操作显然过于昂贵,因此c++11中的原子变量提供了一个可使此函数既线程安全又可重入(而且还更简洁)的替代方案:

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

外部連結 编辑

  • Thread-safe Tcl Extensions (页面存档备份,存于互联网档案馆)(wiki page)
  • Article "" by Bill Venners
  • Article "" by Phillip Bridgham

线程安全, 是程式設計中的术语, 指某个函数, 函数库在多執行緒环境中被调用时, 能够正确地处理多个執行緒之间的公用變數, 使程序功能正确完成, 假設有間銀行只有, 1000, 而兩個人同時提領, 1000, 元時就可能會拿到總計, 2000, 元的金額, 為了避免這個問題, 該間銀行提款時應該使用互斥鎖, 即意味著針對同一個資源處理時, 前一個人提領交易完成後才處理下一筆交易, 但這種手法會使得效能降低, 一般来说, 的函数应该为每个调用它的线程分配专门的空间, 来储存需要单独保存的状态, 如果需要的话, 不依赖. 线程安全是程式設計中的术语 指某个函数 函数库在多執行緒环境中被调用时 能够正确地处理多个執行緒之间的公用變數 使程序功能正确完成 假設有間銀行只有 1000 元 而兩個人同時提領 1000 元時就可能會拿到總計 2000 元的金額 為了避免這個問題 該間銀行提款時應該使用互斥鎖 即意味著針對同一個資源處理時 前一個人提領交易完成後才處理下一筆交易 但這種手法會使得效能降低 一般来说 线程安全的函数应该为每个调用它的线程分配专门的空间 来储存需要单独保存的状态 如果需要的话 不依赖于 线程惯性 把多个线程共享的变量正确对待 如 通知编译器该變數为 易失 volatile 型 阻止其进行一些不恰当的优化 而且 线程安全的函数一般不应该修改全局对象 很多C库代码 比如某些strtok的实现 它将 多次调用中需要保持不变的状态 储存在静态变量中 导致不恰当的共享 不是线程安全的 在多執行緒环境中调用这些函数时 要进行特别的预防措施 或者寻找别的替代方案 例子 编辑在下面这段代码中 函数increment counter是线程安全的 但不是可重入的 include lt pthread h gt int increment counter static int counter 0 static pthread mutex t mutex PTHREAD MUTEX INITIALIZER pthread mutex lock amp mutex only allow one thread to increment at a time counter store value before any other threads increment it further int result counter pthread mutex unlock amp mutex return result 上面的代码中 函数increment counter可以在多个线程中被调用 因为有一个互斥锁mutex来同步对共享变量counter的访问 但是如果这个函数用在可重入的中断处理程序中 如果在pthread mutex lock amp mutex 和pthread mutex unlock amp mutex 之间产生另一个调用函数increment counter的中断 则会第二次执行此函数 此时由于mutex已被lock 函数会在pthread mutex lock amp mutex 处阻塞 并且由于mutex没有机会被unlock 阻塞会永远持续下去 简言之 问题在于 pthread 的 mutex 不可重入 解决办法是设定 PTHREAD MUTEX RECURSIVE 属性 然而对于给出的问题而言 专门使用一个 mutex 来保护一次简单的增量操作显然过于昂贵 因此c 11中的原子变量提供了一个可使此函数既线程安全又可重入 而且还更简洁 的替代方案 include lt atomic gt int increment counter static std atomic lt int gt counter 0 increment is guaranteed to be done atomically int result counter return result 外部連結 编辑Thread safe Tcl Extensions 页面存档备份 存于互联网档案馆 wiki page Thread safe design Article Design for thread safety by Bill Venners Article Write thread safe servlets by Phillip Bridgham 取自 https zh wikipedia org w index php title 线程安全 amp oldid 72658983, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。