歡迎您光臨本站 註冊首頁

linux多線程之線程資源的釋放

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  

 一般來說,對一段運行代碼進行加鎖然後解鎖,如下所示:

  pthread_mutex_lock(&mutex);

  //運行代碼;

  pthread_mutex_unlock(&mutex);

  如果在運行代碼這塊發生錯誤,有異常,導致這個線程異常退出,那麼怎麼辦,pthread_unlock沒有得到調用,那麼這個鎖資源沒有解鎖。可以用下面的方法修改。

  pthread_cleanup_push(pthread_mutex_unlock, (void *) &mutex);

  pthread_mutex_lock(&mutex);

  /* do some work */

  pthread_mutex_unlock(&mutex);

  pthread_cleanup_pop(0);

  這樣假如運行代碼發生錯誤時沒有調用到解鎖,pthread_cleanup_up會自動來調用,參數為0表示不執行push進來的函數。

  但是如果是異常錯誤的話,這個參數並不影響異常終止時清理函數的執行。

  必須要注意的是,如果線程處於PTHREAD_CANCEL_ASYNCHRONOUS狀態,上述代碼段就有可能出錯,因為CANCEL事件有可能在pthread_cleanup_push()和pthread_mutex_lock()之間發生,或者在pthread_mutex_unlock()和pthread_cleanup_pop()之間發生,從而導致清理函數unlock一個並沒有加鎖的mutex變數,造成錯誤。因此,在使用清理函數的時候,都應該暫時設置成PTHREAD_CANCEL_DEFERRED模式。為此,POSIX的Linux實現中還提供了一對不保證可移植的pthread_cleanup_push_defer_np()/pthread_cleanup_pop_defer_np()擴展函數,功能與以下代碼段相當:

  { int oldtype;

  pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);

  pthread_cleanup_push(routine, arg);

  ...

  pthread_cleanup_pop(execute);

  pthread_setcanceltype(oldtype, NULL);

  }

  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

  設置退出類型pthread_setcanceltype

  #include <pthread.h>

  int pthread_setcanceltype(int type, int *oldtype);

  返回值:函數成功返回0。任何其他返回值都表示錯誤。

  將線程退出類型設置為延遲類型或非同步類型。參數type的取值為PTHREAD_CANCEL_DEFERRED或PTHREAD_CANCEL_ASYNCHRONOUS。

  當一個線程被創建后,預設值是延遲類型。在非同步方式下,線程可以在執行的任何時候被退出。



[火星人 ] linux多線程之線程資源的釋放已經有316次圍觀

http://coctec.com/docs/program/show-post-71618.html