盡量避免多程序多執行緒混用,當下死鎖

2021-08-04 13:45:46 字數 2111 閱讀 1116

一句話總結:父程序建立子程序時,子程序會複製父程序的記憶體(包括鎖狀態),需仔細處理。

1、死鎖例子

#include

#include

#include

#include

pthread_mutex_t mutex = pthread_mutex_initializer;

void

* doit(

void

* arg) ;

nanosleep(&ts,

null);

pthread_mutex_unlock(&mutex);

printf(

"pid = %d end doit ...\n"

,static_cast

<

int>(getpid()));

return

null;

} intmain(

void)

; nanosleep(&ts,

null);

if(fork() == 0)

pthread_join(tid,

null);

printf(

"pid = %d exiting main ...\n"

,static_cast

<

int>(getpid()));

return0;

} 執行結果:

通過查詢程序可以發現死鎖了,子程序3071無法往下執行。

原因:父程序建立的執行緒呼叫doit()後,對mutex加了鎖;此時fork了乙個子程序,子程序複製父程序的記憶體,包括此時的mutex鎖狀態;父程序接著往後執行直到結束,而子程序呼叫了doit(),此時mutex處於加鎖狀態,一直等待,造成死鎖。

2、解決死鎖

如何解決上述問題呢,我們需要在fork子程序前將鎖釋放掉,fork之後再將父程序的鎖加上。用

int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void));

pthread_atfork()在fork()之前呼叫,當呼叫fork時,內部建立子程序前在父程序中會呼叫prepare,內部建立子程序成功後,父程序會呼叫parent ,子程序會呼叫child。

不過還是盡量少將多程序多執行緒混在一起。

#include

#include

#include

#include

pthread_mutex_t mutex = pthread_mutex_initializer;

void

* doit(

void

* arg) ;

nanosleep(&ts,

null);

pthread_mutex_unlock(&mutex);

printf(

"pid = %d end doit ...\n"

,static_cast

<

int>(getpid()));

return

null;

} void

prepare(

void)

void

parent(

void)

void

child(

void)

intmain(

void)

; nanosleep(&ts,

null);

if(fork() == 0)

pthread_join(tid,

null);

printf(

"pid = %d exiting main ...\n"

,static_cast

<

int>(getpid()));

return0;

} 結果:

多執行緒 多程序?

這幾天在思考如何改進原型在多個客戶端的情況下的效能,特地溫習了一下多程序和多執行緒的一些知識。在linux下程序的程序和執行緒在核心看來區別很小,都是乙個可排程單元,都擁有記憶體管理結構等等。但是關鍵的差別是程序的資源都是私有的,而執行緒則是和別人共享的,所以執行緒的上下文切換可能比程序的開銷要小很...

多程序,多執行緒

多工程式設計 通過應用程式利用多個計算機核心達到多工同時執行的 目的,從此來提公升程式執行效率 多程序,多執行緒 程序 程式在計算機中一次執行的過程 程式 靜態的描述,不占有計算機資源 程序 是乙個動態的過程,占有cpu,記憶體等計算機資源 有一定的生命週期 同乙個程式,每次執行都是不同的程序,因為...

多執行緒 多程序

是什麼?能幹什麼?單執行緒情況下,執行效率低。系統的資源沒有得到充分利用。計算密集型 運算量比較大 io密集型 cpu空閒,輸入輸出較多 怎麼幹?爬蟲 io密集型 多執行緒 橫向 所有的程式的執行都在乙個執行緒中,程式啟動時,啟動多執行緒,每個執行緒跑同樣的 縱向 將程式進行拆分,每個執行緒跑特定的...