pthread_cleanup_push與pthread_cleanup_pop的目的 作用

http://blog.csdn.net/slj_win/article/details/7267483

首先你必須知道pthread_cleanup_push與pthread_cleanup_pop的目的(作用)是什么。

比如thread1:
執行
pthread_mutex_lock(&mutex);

//一些會阻塞程序運行的調用,比如套接字的accept,等待客戶連接
sock = accept(......);? ?? ?? ?? ?//這里是隨便找的一個可以阻塞的接口

pthread_mutex_unlock(&mutex);
這個例子中,如果線程1執行accept時,線程會阻塞(也就是等在那里,有客戶端連接的時候才返回,或則出現其他故障),線程等待中......

這時候線程2發現線程1等了很久,不賴煩了,他想關掉線程1,于是調用pthread_cancel()或者類似函數,請求線程1立即退出。

這時候線程1仍然在accept等待中,當它收到線程2的cancel信號后,就會從accept中退出,然后終止線程,注意這個時候線程1還沒有執行:
pthread_mutex_unlock(&mutex);
也就是說鎖資源沒有釋放,這回造成其他線程的死鎖問題

所以必須在線程接收到cancel后用一種方法來保證異常退出(也就是線程沒達到終點)時可以做清理工作(主要是解鎖方面),pthread_cleanup_push與pthread_cleanup_pop就是這樣的。

pthread_cleanup_push(some_clean_func,...)
pthread_mutex_lock(&mutex);

//一些會阻塞程序運行的調用,比如套接字的accept,等待客戶連接
sock = accept(......);? ?? ?? ?? ?//這里是隨便找的一個可以阻塞的接口

pthread_mutex_unlock(&mutex);
pthread_cleanup_pop(0);
return NULL;
上面的代碼,如果accept被cancel后線程退出,會自動調用some_clean_func函數,在這個函數中你可以釋放鎖資源。如果accept沒有被cancel,那么線程繼續執行,當pthread_mutex_unlock(&mutex);表示線程自己正確的釋放資源了,而執行pthread_cleanup_pop(0);也就是取消掉前面的some_clean_func函數。接著return線程就正確的結束了。

不曉得你明白沒,通俗點就是:
pthread_cleanup_push注冊一個回調函數,如果你的線程在對應的pthread_cleanup_pop之前異常退出(return是正常退出,其他是異常),那么系統就會執行這個回調函數(回調函數要做什么你自己決定)。但是如果在pthread_cleanup_pop之前沒有異常退出,pthread_cleanup_pop就把對應的回調函數取消了,

關于取消點的解釋:

比如你執行:
? ?? ???printf("thread sleep\n");
? ?? ???sleep(10);
? ?? ???printf("thread wake...\n");
在sleep函數中,線程睡眠,結果收到cancel信號,這時候線程從sleep中醒來,但是線程不會立刻退出。這是應為pthread與C庫方面的原因(具體是啥我也不清楚),pthread的建議是,如果一個函數是阻塞的,那么你必須在這個函數前后建立取消點,比如:
? ?? ???printf("thread sleep\n");
? ?? ???pthread_testcancel();
? ?? ???sleep(10);
? ?? ???pthread_testcancel();
? ?? ???printf("thread wake...\n");
這樣,就添加了兩個取消掉。在執行到pthread_testcancel的位置時,線程才可能響應cancel退出進程。

額外的知識:
對于cancel信號,線程有兩種方法: 忽略,和響應。默認是響應
接收到cancel信號,線程有兩種處理類型: 立即響應 和 延遲響應(在最近的取消點響應),默認是延遲響應

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/384222.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/384222.shtml
英文地址,請注明出處:http://en.pswp.cn/news/384222.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

動態規劃淺談

接觸動態規劃這么久了,簡單談一下自己對動態規劃的理解。 動態規劃名字聽起來好像比比較高大上,可是事實上,人家就是比較高大上。(抖個機靈) 剛開始接觸動態規劃的時候覺得好可怕,這么復雜的問題我怎么能想…

Linux多線程——使用信號量同步線程

http://blog.csdn.net/ljianhui/article/details/10813469/ 信號量、同步這些名詞在進程間通信時就已經說過,在這里它們的意思是相同的,只不過是同步的對象不同而已。但是下面介紹的信號量的接口是用于線程的信號量,注意不要跟用于進程間通信…

linux下安裝erlang

1.安裝Erlang編譯依賴: yum -y install gcc glibc-devel make ncurses-devel openssl-devel xmlto perl wget 2.下載Erlang: wget http://www.erlang.org/download/otp_src_19.3.tar.gz 3.解壓并安裝 tar -xzvf otp_src_19.3.tar.gz cd otp_src_19.3 ./configure --…

Linux 線程同步的三種方法

http://blog.csdn.net/zsf8701/article/details/7844316 線程的最大特點是資源的共享性,但資源共享中的同步問題是多線程編程的難點。linux下提供了多種方式來處理線程同步,最常用的是互斥鎖、條件變量和信號量。 一、互斥鎖(mutex) 通過鎖機制實現線程…

Elixir特性

iex 退出:Ctrl-C 或Ctrl-G再輸入q 回車。 幫助文檔:h 查看輔函數列表 h IO 查看IO模塊幫助 h IO.puts 查看IO模塊中的puts函數的文檔 編譯和運行:創建一個hello.exs的文件。IO.puts "hello world"    //輸出hello world 使用el…

Elixir基礎

值類型 整數,包括十進制(1234)、十六進制(0xcafe)、八進制(0o765)和二進制(0b1010) 浮點數 原子,原子是常量,用于表現某些東西的名字,…

C++11新特性之八——函數對象function

http://www.cnblogs.com/yyxt/p/3987717.html 詳細請看《C Primer plus》(第六版中文版) http://www.cnblogs.com/lvpengms/archive/2011/02/21/1960078.html 備注: 函數對象: 盡管函數指針被廣泛用于實現函數回調,但C還提供了一個重要的實現…

分塊思想

今天學習了一個算法(這個應該叫做算法吧?)叫做分塊(和莫隊,但是莫隊還沒有搞懂,搞懂再來寫吧) 聽起來很高級,蒟蒻表示瑟瑟發抖。但是學完發現怎么那么像是一種變相的暴力呢。 分塊思…

從零開始學C++之STL(八):函數對象、 函數對象與容器、函數對象與算法

http://blog.csdn.net/jnu_simba/article/details/9500219 一、函數對象 1、函數對象(function object)也稱為仿函數(functor) 2、一個行為類似函數的對象,它可以沒有參數,也可以帶有若干參數。 3、任何重載…

樹狀數組初步理解

學習樹狀數組已經兩周了,之前偷懶一直沒有寫,趕緊補上防止自己忘記(雖然好像已經忘得差不多了)。 作為一種經常處理區間問題的數據結構,它和線段樹、分塊一樣,核心就是將區間分成許多個小區間然后通過對大區…

命名函數

函數體是代碼塊 代碼塊do...end是一種表達式的組織方式。 # ./times.exs下defmodule Times dodef doule(n) don * 2end end 函數調用與模式匹配 代碼如下: # ./factorial.exs    計算階層 defmodule Factorial dodef of(0), do: 1          #終止條件…

STL運用的C++技術(6)——函數對象

http://blog.csdn.net/wuzhekai1985/article/details/6658940?_t_t_t0.20427969420870595 STL是C標準庫的重要組成部分之一,它不僅是一個可復用的組件庫,更是一個包含算法與數據結構的軟件框架,同時也是C泛型編程的很好例子。STL中運用了許多…

列表與遞歸

頭部和尾部 [head | tail ] [1] #head 1 tail [] [head | tail ] [1, 2, 3] #head 1 tail [2, 3] [head | tail ] [] #報錯 創建映射函數 我們可以使用一個函數來處理列表中的各個元素,如此可以接受更加復雜的處理,也可以…

優先隊列小結

不像棧和隊列,雖然STL有較好實現但是我們自己也可以很方便的實現,優先隊列自己實現起來就比較復雜,比較浪費時間(而且自己目前也不會233)而優先隊列因為其較好的特性經常被使用,因此對它的熟練掌握是做題的…

字典:散列表、散列字典、關鍵字列表、集合與結構體

字典 散列表和散列字典都實現了Dict的行為。Keyword模塊也基本實現了,不同之處在于它支持重復鍵。 Eunm.into可以將一種類型的收集映射轉化成另一種。 defmodule Sum dodef values(dict) dodict |> Dict.values |> Enum.sumend endhd [ one: 1, two: 2, thre…

C++11 學習筆記 lambda表達式

http://blog.csdn.net/fjzpdkf/article/details/50249287 lambda表達式是C11最重要也最常用的一個特性之一。lambda來源于函數式編程的概念,也是現代編程語言的一個特點。 一.函數式編程簡介 定義:簡單說,“函數式編程”是一種“編程范式”。…

Cutting Codeforces Round #493 (Div. 2)

Cutting There are a lot of things which could be cut — trees, paper, “the rope”. In this problem you are going to cut a sequence of integers. There is a sequence of integers, which contains the equal number of even and odd numbers. Given a limited bud…

Enum、Stream

Enum 其常見用法見&#xff1a;https://cloud.tencent.com/developer/section/1116852 在sort時&#xff0c;如果要獲得穩定的排序結果&#xff0c;要使用< 而不是 <。 Stream Stream是延遲處理的&#xff0c;而Enum是貪婪的&#xff0c;則意味著傳給它一個收集&#xff…

linux網絡編程之posix 線程(三):posix 匿名信號量與互斥鎖 示例生產者--消費者問題

http://blog.csdn.net/jnu_simba/article/details/9123603 一、posix 信號量 信號量的概念參見這里。前面也講過system v 信號量&#xff0c;現在來說說posix 信號量。 system v 信號量只能用于進程間同步&#xff0c;而posix 信號量除了可以進程間同步&#xff0c;還可以線程間…

洛谷P1080-國王游戲-貪心+高精度

P1080-國王游戲 啊啊啊&#xff0c;剛才已經寫了一次了&#xff0c;但是Edge瀏覽器不知道為什么卡住了&#xff0c;難受。 好吧&#xff0c;其實是一道可做題&#xff0c;分析得到的貪心策略就是就是將a * b小的放在前面&#xff08;其他的懶得說了&#xff09;&#xff0c;主要…