子程序繼承父程序中互斥鎖的討論

2021-07-02 18:49:01 字數 2399 閱讀 9665

1. 引言

首先明確乙個問題:如果乙個多執行緒程式的某個執行緒呼叫了fork函式,那麼新建立的子程序裡是不會自動建立和父程序相同數量的執行緒的,它只是呼叫fork的那個執行緒的完整複製。並且,子程序會自動繼承父程序中(包括父程序在呼叫fork之前建立的執行緒)互斥鎖的狀態。也就是說,父程序中已經被加鎖的互斥鎖在子程序中也是被鎖住的。這就引起了乙個問題:子程序可能不清楚從父程序繼承過來的互斥鎖的具體狀態(是加鎖狀態還是解鎖狀態)。這個互斥鎖可能被加鎖了,但並不是由呼叫fork函式的那個執行緒鎖住的,而是由其他執行緒鎖住的。如果是這種情況,則子程序若再次對該互斥鎖執行加鎖操作就會導致死鎖。下面討論子程序繼承父程序互斥鎖的幾種情況。

2. 繼承父程序建立的鎖

死鎖!可以看到,父程序之前先加了鎖,子程序繼承了加鎖的狀態後,嘗試加鎖時被阻塞,即便3秒後父程序解了鎖,子程序還是不能進行加鎖操作,因為fork之後子程序對父程序的動作是不可見的,因此子程序陷入了永遠的阻塞狀態。

3. 父程序的子執行緒在fork前執行了加鎖操作

死鎖!fork之前睡眠1秒是為了讓子執行緒先執行加鎖。可以看到,子執行緒加鎖後,子程序繼承了互斥鎖的狀態,無法執行加鎖操作,被阻塞。即便後來子執行緒解了鎖,子程序還是繼續阻塞。說明子程序只是繼承了鎖的狀態,對後來的解鎖動作並不可見。

4. 子執行緒在fork之後加鎖

正常!在fork之前子執行緒還沒有加鎖,子程序成功加鎖,再解鎖前,子執行緒也執行了加鎖操作,之後兩者都順利解了鎖。說明子程序繼承的只是fork之前父程序(包括其子執行緒)已執行過的鎖操作狀態,fork之後父子各自對鎖的操作是不可見的。

5. 子執行緒建立的執行緒中執行了加鎖

死鎖!鎖的狀態仍然被子程序繼承了。

多程序中的程序鎖(互斥鎖)

以下例項中 import threading lock threading.lock num 0def work1 asd global num for i in range asd num 1print 在當前的執行緒修改過後的num是 num defwork2 asd global num fo...

fork 子程序不繼承父程序開啟的檔案描述符

昨天面試被問到了這個問題,沒有回答上來,網上找了一下答案。解決方法是使用clone系統呼叫使用引數在複製時將父程序資源有選擇地複製給子程序。下面介紹forkvforkclone三者的區別 vfork系統呼叫不同於fork,用vfork建立的子程序與父程序共享位址空間,也就是說子程序完全執行在父程序的...

Linux子程序繼承父程序的檔案描述符

include include include include include include include int main pid t pid int ret 0 int fd open temp.txt o creat o trunc o rdwr,0666 if fd 1 if pid f...