pthread sigmask 控制線程的訊號掩碼

2021-07-25 08:35:37 字數 4697 閱讀 5232

示例1:

/* 示例一:遮蔽訊號sigint

編譯:gcc pthread_sigmask1.c -lpthread

執行後,你發現你按下ctrl+c(觸發sigint訊號),這個程式根本停不下來。因為sigint訊號已經如我們所願被遮蔽掉了。

*/#include #include #include #include int main(int argc, char** argv)

示例二:主程序建立出來的執行緒將繼承主程序的掩碼

/* 示例二:主程序建立出來的執行緒將繼承主程序的掩碼

編譯:gcc pthread_sigmask2.c -lpthread

執行後,你可以發現,子執行緒果然接收不到pthread_kill傳送給自己的sigint訊號,

但可以收到sigusr1訊號!本來要休眠300s,但是收到了sigusr1訊號,

才休眠5秒就(提前294秒)醒來say goodbye了。

執行結果:

[lgh@lghvm001 thread]$ ./a.out

[main][139999919077120] working hard ...

>>> thread[139999919068928] running ......

[main][139999919077120] send signal sigint ...

thread[139999919068928] catch signo = 10

thread[139999919068928] waitup(294), and say good bye!

[main][139999919077120] good bye and good luck!

[lgh@lghvm001 thread]$

*/#include #include #include #include void handler(int signo)

void* run(void *param)

int main(int argc, char** argv)

示例三:子執行緒可以後天培養自己對訊號的喜好

/* 示例三:子執行緒可以後天培養自己對訊號的喜好

編譯:gcc pthread_sigmask3.c -lpthread

子執行緒天生繼承了主線程對訊號的喜好,但是自己可以通過後天的努力改變。

由此可見,linux裡的每個執行緒有自己的訊號掩碼,所以使用pthread_kill給指定執行緒傳送訊號時,

一定謹慎設定好執行緒的訊號掩碼。

當然,用kill傳送訊號,在多執行緒環境下,kill所產生的訊號時傳遞到整個程序的,

並且所有執行緒都有機會收到這個訊號,但具體是哪個執行緒處理這個訊號,就不一定。

一般情況下,都是主線程處理這個訊號。

執行結果:

[lgh@lghvm001 thread]$ gcc pthread_sigmask3.c -lpthread

[lgh@lghvm001 thread]$ ./a.out

[main][140613382825728] working hard ...

>>> [1481543657]thread[140613382817536] running ......

[main][140613382825728] send signal sigusr1 ...

[1481543841]thread[140613382825728] catch signo = 10 ... //子執行緒sleep期間,kill -sigusr1 2839

[1481543861]thread[140613382825728] catch signo = 10 ... done

[1481543957]thread[140613382817536] waitup(0), and say good bye!

[main][140613382825728] good bye and good luck!

[lgh@lghvm001 thread]$

*/#include #include #include #include void handler(int signo)

void* run(void *param)

int main(int argc, char** argv)

示例四:主線程收到訊號,沒處理完,又來乙個訊號,子執行緒會處理嗎? 會!

/* 示例四:主線程收到訊號,沒處理完,又來乙個訊號,子執行緒會處理嗎? 會!

編譯:gcc pthread_sigmask4.c -lpthread

在乙個命令列終端啟動a.out,在另乙個命令列終端傳送4次sigusr1訊號給a.out程序

執行結果:

[lgh@lghvm001 thread]$ ./a.out

[main][139796483913472] working hard ...

>>> [1481545031]thread[139796483905280] running ...... //此時傳送四次kill -sigusr1 2886,2886為a.out的程序號

[1481545054]thread[139796483913472] catch signo = 10 ...

[1481545055]thread[139796483905280] catch signo = 10 ...

[1481545056]thread[139796483913472] catch signo = 10 ... done

[1481545056]thread[139796483913472] catch signo = 10 ...

[1481545057]thread[139796483905280] catch signo = 10 ... done

[1481545057]thread[139796483905280] catch signo = 10 ...

[1481545058]thread[139796483913472] catch signo = 10 ... done

[1481545059]thread[139796483905280] catch signo = 10 ... done

>>> [1481545059]thread[139796483905280] waitup(35), and say good bye!

[main][139796483913472] good bye and good luck!

[lgh@lghvm001 thread]$

*/#include #include #include #include void handler(int signo)

void* run(void *param)

int main(int argc, char** argv)

如果把void handler(int signo)函式中的sleep(2)注釋掉,執行結果如下:

[lgh@lghvm001 thread]$ ./a.out 

[main][140353429055232] working hard ...

>>> [1481596389]thread[140353429047040] running ......     //此處傳送6次「kill -sigusr1 3123」

[1481596401]thread[140353429055232] catch signo = 10 ...

[1481596401]thread[140353429055232] catch signo = 10 ... done

[1481596401]thread[140353429055232] catch signo = 10 ...

[1481596401]thread[140353429055232] catch signo = 10 ... done

[1481596402]thread[140353429055232] catch signo = 10 ...

[1481596402]thread[140353429055232] catch signo = 10 ... done

[1481596402]thread[140353429055232] catch signo = 10 ...

[1481596402]thread[140353429055232] catch signo = 10 ... done

[1481596402]thread[140353429055232] catch signo = 10 ...

[1481596402]thread[140353429055232] catch signo = 10 ... done

[1481596403]thread[140353429055232] catch signo = 10 ...

[1481596403]thread[140353429055232] catch signo = 10 ... done

>>> [1481596449]thread[140353429047040] waitup(0), and say good bye!

[main][140353429055232] good bye and good luck!

[lgh@lghvm001 thread]$

可見,若子執行緒「沒空」(在sleep),主線程有空,訊號都給主線程處理了。

星空 控控控 上ke控 新浪部落格

摸不到的顏色是否叫彩虹 看不到的擁抱是否叫做微笑 乙個人想著乙個人 是否就叫寂寞 命運偷走如果只留下結果 時間偷走初衷只留下苦衷 你來過然後你走後 只留下星空 那一年我們望著星空 有那麼多的燦爛的夢 以為快樂會永久 像不變星空 陪著我獵戶天狼 侄女光年外的寂寞 回憶青春 夢想何時常常隱沒 我愛過然後...

A司密事 控控控 上ke控 新浪部落格

設計模式 1.學習方法 先看名字,後寫 2.總共23種設計模式 3.使用 a.第一次決定使用不使用,盡量大膽使用。b.第二次要修改 發現適用設計模式,使用它。如 頻繁改 c.不會的dm,則不用 codding style 1.文件注釋 2.不應有tab,行前 3.不應有space,行後 4.使用fo...

串列埠流控 軟體流控與硬體流控

在序列通訊處理中,常常看到rts cts和xon xoff這兩個選項,這就是兩個流控制的選項,目前流控制主要應用於數據機的資料通訊中。那麼,流控制在序列通訊中有何作用,在編制序列通訊程式怎樣應用呢?下面我們就談談這個問題。1.流控制在序列通訊中的作用 這裡講到的 流 當然指的是資料流。資料在兩個串列...