linux執行緒控制

2021-08-04 10:55:33 字數 4700 閱讀 2552

1.執行緒屬性

a) 分離狀態

不需要了解執行緒返回終止狀態時設定

b) 棧末尾警戒緩衝區

避免棧溢位的擴充套件記憶體大小,一般系統設定為頁的整數倍

c) 棧的最小位址

i. 當有許多執行緒時,減少棧大小

ii. 當執行緒中有許多自動變數時,則增大棧大小

d) 棧的最小長度

2.互斥量屬性

a) 程序共享屬性

i. 預設:pthread_process_private,多執行緒訪問同乙個同步物件。

ii. pthread_process_shared,多程序將鎖對映到自己空間,實現多程序同步

b) 健壯屬性(解決:多程序間,持有的程序終止時,互斥量鎖定,其他程序阻塞)

i. 預設:pthread_mutex_stalled,程序會被拖住

ii. pthread_mutex_robust,程序終止時未解鎖,從

pthread_mutex_lock()

的返回值為

eownerdead

而不是0

,通過返回值進行恢復處理。(恢復時執行緒先呼叫

pthread_mutex_consistent

(&m_lock),

再進行pthread_mutex_unlock(&m_lock)

解鎖;否則應用狀態無法恢復,解鎖後,互斥量將永久不可以)

c) 型別屬性

pthread_mutex_recursive:可用於遞迴

3.讀寫鎖,條件變數,屏障屬性

只支援程序共享屬性

4.執行緒與訊號(訊號處理是程序中所有執行緒共享的)

在多執行緒中處理訊號的原則卻完全不同,它的基本原則是:

將對訊號的非同步處理,

轉換成同步處理

,也就是說

用乙個執行緒專門的來「同步等待

」訊號的到來

,而其它的執行緒可以完全不被該訊號中斷/打斷

(interrupt)

。這樣就在相當程度上簡化了在多執行緒環境中對訊號的處理。而且可以保證其它的執行緒不受訊號的影響。

sigwait函式使用乙個訊號集作為他的引數,並且在集合中的任乙個訊號發生時返回該訊號值,解除阻塞,然後可以針對該訊號進行一些相應的處理。

在多執行緒程式中,乙個執行緒可以使用pthread_kill對同乙個程序中指定的執行緒(包括自己)傳送訊號。

在多執行緒**中,總是使用

sigwait

或者sigwaitinfo

或者sigtimedwait

等函式來處理訊號。

可以使用pthread_sigmask函式來

遮蔽某個執行緒對某些訊號的

響應處理

,僅留下需要處理該訊號的執行緒來處理指定的訊號。實現方式是:利用執行緒訊號遮蔽集的繼承關係(在主程序中對sigmask進行設定後,主程序建立出來的執行緒將

繼承主程序的掩碼

)呼叫sigwait同步等待的訊號必須在呼叫執行緒中被遮蔽,並且通常應該在所有的執行緒中被遮蔽(這樣可以保證訊號絕不會被送到除了呼叫

sigwait

的任何其它執行緒),這是通過利用訊號掩碼的繼承關係來達到的。

1. static void

*sig_thread

(void 

*arg)

2. 

12. }

13. 

14. 

int

1. main

(int

argc

,char 

*argv)

15. 

通過在主線程中阻塞一些訊號,其它的執行緒會繼承訊號掩碼,然後專門用乙個執行緒使用sigwait函式來同步的處理訊號,使其它的執行緒不受到訊號的影響。

1. digdeep@ubuntu

:~/pthread$ gcc 

-wall 

-pthread 

-o sigwait_test sigwait_test.c 

2. digdeep@ubuntu

:~/pthread$ 

./sigwait_test 

3. receive signal.10

4. receive signal.12

5. receive signal.34

6. receive signal.34

7. receive signal.36

8. receive signal.36

9. receive signal.64

10. 

receive signal.64

11. 

digdeep@ubuntu

:~/pthread$

從以上測試程式發現以下規則:

· 對於

非實時訊號,相同訊號不能在訊號佇列中排隊

;對於實時訊號,相同訊號可以在訊號佇列中排隊。· 

如果訊號佇列中有多個實時以及非實時訊號排隊,

實時訊號並不會先於非實時訊號被取出

,訊號數字小的會先被取出

:如 sigusr1(

10)會先於

sigusr2 (12)

,sigrtmin(34

)會先於

sigrtmax (64)

, 非實時訊號因為其訊號數字小而先於實時訊號被取出。

· sigstop和

sigkill。· 

sigfpe、

sigill

、sigsegv

、sigbus。· 

確保 sigwait() 等待的訊號集已經被程序中所有的執行緒

阻塞

· 在主線程或其它工作執行緒產生訊號時,

必須呼叫 kill() 將訊號發給整個程序

,而不能使用 pthread_kill() 傳送某個特定的

工作

執行緒

,否則訊號處理執行緒無法接收到此訊號。

· 因為 sigwait()使用了序列的方式處理訊號的到來,為避免訊號的處理存在滯後,或是非實時訊號被丟失的情況,處理每個訊號的**應盡量簡潔、快速,避免呼叫會產生阻塞的庫函式。

5.執行緒與fork

子程序繼承了父程序的互斥量、讀寫鎖、條件變數的條件狀態

若子程序fork後立馬呼叫

exec

可避免死鎖等問題;

可通過int pthread_atfork(void (*prepare)(void),void (*parent)(void),void (*child)(void));清理鎖的狀態。

prepare:獲取父程序定義的鎖;(父程序在

fork

建立子程序前

呼叫)

parent:對獲取的鎖進行解鎖;

(父程序在fork建立子程序後,

返回父程序前

呼叫)

child:

對獲取的鎖進行解鎖;(父程序在fork返回子程序前

呼叫)

#include

pthread_mutex_t lock1 = pthread_mutex_initialized;

pthread_mutex_t lock2 = pthread_mutex_initialized;

void prepare(void)

int err;

printf("prepare\n");

if((err = pthread_mutex_lock(&lock1))!= 0)

if((err = pthread_mutex_lock(&lock2))!= 0)

void parent(void)

int err;

printf("parent\n");

if((err = pthread_mutex_unlock(&lock1))!= 0)

if((err = pthread_mutex_unlock(&lock2))!= 0)

void child(void)

int err;

printf("child\n");

if((err = pthread_mutex_unlock(&lock1))!= 0)

if((err = pthread_mutex_unlock(&lock2))!= 0)

void *thr_func(void *arg)

printf("thread run\n");

pause();

return(0);

int main()

int err;

pid_t pid;

pthread_t tid;

if((err = pthread_atfork(prepare,parent,child))!=0)

if((err = pthread_create(&tid,null,thr_func,null))!=0)

sleep(2);

printf("parent to fork\n");

if((pid = fork()) < 0)

else if(pid == 0)

else

exit(0);

結果是:

fork()-->prepare()-->child()--->pid=0---->parent()---->pid>0

Linux 執行緒控制

話不多說,直接進入正題!1.什麼是執行緒?2.執行緒控制 2.1 執行緒建立int pthread create pthread t tid,pthread attr t attr,void start routine void void arg tid 返回執行緒id attr 設定執行緒的屬性,...

《Linux》 執行緒控制

posix執行緒庫 與執行緒有關的函式構成了乙個完整的系列,絕大多數函式的名字都是以 pthread 打頭的 要使用這些函式庫,要通過引入頭文 鏈結這些執行緒函式庫時要使用編譯器命令 lpthread 選項 建立執行緒 功能 建立乙個新的執行緒 原型 int pthread create pthre...

linux多執行緒控制

include include include include include define size 1024 函式作用 使用訊號量控制,讀取輸入,獲得長度 void thread function void argv char buf size sem t sem int main res pt...