多執行緒程式設計基礎

2021-07-23 06:01:55 字數 4632 閱讀 4666

值得參考:

#include int pthread_create(thread_id, attr, func, arg)

其中func表示該執行緒需要執行的**位址

從執行緒**處return

pthread_cancle終止同一程序中的另一線程

呼叫pthread_exit來終止自己

設定取消執行緒的狀態和型別

pthread_setcancelstate() 有三種狀態:

pthread_cancel_enable表示執行緒是可以取消的

pthread_cancel_disable 表示執行緒是不可取消的

pthread_cancel_deferred 表示執行緒是可以延遲取消的,就是收到取消請求後,會繼續執行下去,直到找到下乙個取消點

類似pthread_join,pthread_cond_wait都是取消點

pthread_cancel_asynchronous表示非同步取消方式,表示執行緒收到取消請求後,立即取消退出

預設情況下,乙個執行緒是可取消的,並且是同步取消

如果乙個執行緒正執行到乙個鎖內,已經獲得鎖了,這是如果它因為異常退出了,那麼此時就是乙個死鎖的問題

執行緒在結束的時候,會自動執行乙個cleanup函式控制代碼,這個函式控制代碼裡有乙個stack,通過pthread_cleanup_push往這個stack裡壓入函式,

退出的時候,cleanup函式,會自動從這些棧裡拿出函式執行

如果函式沒有異常退出,那這些棧內的函式如何處理?

通過pthread_cleanup_pop彈出這些函式

可使用pthread_join來掛起執行緒,等待終止

int pthread_join(threaded, value_ptr)

一般情況下,執行緒終止後,其終止狀態一直保留到其它執行緒呼叫pthread_join獲取它的狀態為止。但是執行緒也可以被置為detach狀態,這樣的執行緒一旦終止就立刻**它占用的所有資源,而不保留終止狀態。不能對乙個已經處於detach狀態的執行緒呼叫pthread_join,這樣的呼叫將返回einval 。對乙個尚未detach的執行緒呼叫pthread_join或pthread_detach都可以把該執行緒置為detach狀態,也就是說,不能對同一執行緒呼叫兩次pthread_join,或者如果已經對乙個執行緒呼叫了pthread_detach就不能再呼叫pthread_join了。

pthread_kill(id, sig)

傳送訊號到執行緒,若sig=0,是乙個保留訊號,用來檢測線程是否存活

返回值esrch表示執行緒已經不存在了

返回值einval表示非法的訊號

返回其他值表示執行緒還存在

int pthread_detach(threadid)

entry()執行緒入口函式宣告為static模式

c++中的std::thread類

封裝thread為c++類

條件變數是一種同步機制,允許執行緒掛起,直到共享資料上的某些條件得到滿足。條件變數上的基本操作有:觸發條件(當條件變為 true 時);等待條件,掛起執行緒直到其他執行緒觸發條件。條件變數要和互斥量相聯結,以避免出現條件競爭--乙個執行緒預備等待乙個條件變數,當它在真正進入等待之前,另乙個執行緒恰好觸發了該條件。

一般的程式設計方法:

pthread_mutex_lock(); //獲取互斥量

while(condition_is_false) //等待其他的執行緒修改條件,觸發條件變數

pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t * mutex);

pthread_mutex_unlock(); //釋放互斥量

以下的**片段用來避免無限制的等待:

pthread_mutex_t count_lock; 

pthread_cond_t count_nonzero; 

unsigned count;

void decrement_count()

void increment_count()

下面的例子更是提醒程式設計師慎用pthread_cond_broadcast函式

#include pthread_mutex_t rsrc_lock; 

pthread_cond_t rsrc_add;

unsigned int resources;

get_resources(int amount)

add_resources(int amount)

這三個例子告訴我們,要確保不進入無限的等待,要在改變狀態之前加鎖,改變完成之後解鎖。

foolscap:針對某些特定場景下的應用,不必生搬硬套的使用http,或者實現另外一種rpc方法。若需要在雙方都要使用方法呼叫,那麼foolscap是乙個不錯的選擇。

多執行緒程式中,解決訪問衝突的最常用的方法是:互斥鎖mutex(mutual exclusive lock),組成「讀-修改-寫」的原子操作;互斥鎖保護的是lock之後所有的變數。

建立和初始化

pthread_mutex_t

pthread_mutex_init(pthread_mutex_t *mutex, constpthread_mutexattr_t *attr)初始化mutex,使用屬性attr,若attr為null,則表示使用預設屬性。

pthread_mutex_destroy(pthread_mutex_t *mutex)

加鎖

int pthread_mutex_lock(pthread_mutex_t *mutex)

int pthread_mutex_trylock(pthread_mutex_t *mutex)

int pthread_mutex_unlock(pthread_mutex_t *mutex)

乙個執行緒可以呼叫

pthread_mutex_lock

獲得mutex

,如果這時另乙個執行緒已經呼叫

pthread_mutex_lock

獲得了該

mutex

,則當前執行緒需要掛起等待,直到另乙個執行緒呼叫

pthread_mutex_unlock

釋放mutex

,當前執行緒被喚醒,才能獲得該

mutex

並繼續執行。

如果乙個執行緒既想獲得鎖,又不想掛起等待,可以呼叫

pthread_mutex_trylock

,如果mutex

已經被另乙個執行緒獲得,這個函式會失敗返回

ebusy

,而不會使執行緒掛起等待

乙個執行緒先後

2次呼叫

lock

,第二次呼叫時,由於鎖已被占用,該執行緒會掛起等待別的執行緒釋放鎖,然而鎖正是被自己占用,該執行緒又因為掛起沒有機會釋放鎖,因此就永遠處於掛起等待狀態,這是第一種常見的死鎖;

第二種常見的死鎖情況是:執行緒

a獲得了鎖

1 ,執行緒

b 獲得了鎖

2,這時執行緒

a 呼叫

lock

試圖獲得鎖

2,結果是需要掛起等待執行緒

b 釋放鎖

2,而這時執行緒

b 也呼叫

lock

試圖獲得鎖

1,結果是需要掛起等待執行緒

a 釋放鎖

1,於是執行緒a 和

b 都永遠處於掛起狀態了。不難想象,如果涉及到更多的執行緒和更多的鎖,有沒有可能死鎖的問題將會變得複雜和難以判斷。

則應該盡量使用

pthread_mutex_trylock

呼叫代替

pthread_mutex_lock

呼叫,以免死鎖。

busy waiting:

對於單cpu

來說,很是耗費資源;自旋鎖可以在任何時刻防止多於乙個的核心任務同時進入臨界區,因此這種鎖可有效地避免多處理器上併發執行的核心任務競爭共享資源。自旋鎖不允許任務睡眠

(持有自旋鎖的任務睡眠會造成自死鎖

——因為睡眠有可能造成持有鎖的核心任務被重新排程,而再次申請自己已持有的鎖

),它能夠在中斷上下文中使用。

pv操作及訊號量的概念都是由荷蘭科學家

e.w.dijkstra

提出的。訊號量

s是乙個整數,

s大於等於零時代表可供併發程序使用的資源實體數,但

s小於零時則表示正在等待使用共享資源的程序數。

p操作申請資源:(1

)s減1

;(2)若

s減1後仍大於等於零,則程序繼續執行;(3

)若s減1

後小於零,則該程序被阻塞後進入與該訊號相對應的佇列中,然後轉入程序排程。

v操作釋放資源:(1

)s加1

;(2)若相加結果大於零,則程序繼續執行;(3

)若相加結果小於等於零,則從該訊號的等待佇列中喚醒乙個等待程序,然後再返回原程序繼續執行或轉入程序排程。

多執行緒程式設計基礎

一直以來,自己都不會多執行緒的程式設計。今天決定好好的補補!一 多執行緒的基本概念 二 多執行緒中的重要函式 1 handle createthread lpsecurity attributes lpthreadattributes,dword dwstacksize,lpthread start...

C 學習 多執行緒程式設計 多執行緒基礎

c 內建了對多執行緒程式設計的支援功能,所以相對於其他語言在多執行緒方面的問題,c 這裡就已經最小化或者不復存在。在.net framework 4.0中,c 中新增了兩個與多執行緒應用程式相關的重要功能 tpl 任務執行並行庫 和plinq 並行linq 兩者都提供對並行程式設計的支援,都可以利用...

C 多執行緒程式設計基礎

使用執行緒有幾個原因。假設從應用程式中進行網路呼叫需要一定的時間。使用者不希望分割使用者界,並且讓使用者一直等待直到從伺服器返回乙個響應為止。使用者可以同時執行其他一些操作,或者甚至取消傳送給伺服器的請求。這些都可以使用執行緒來實現。對於所有需要等待的操作,例如,因為檔案 資料庫或網路訪問都需要一定...