1. 程式人生 > >多執行緒中的確保子執行緒退出之後 主執行緒退出

多執行緒中的確保子執行緒退出之後 主執行緒退出



Linux下程式設計,執行緒、程序退出順序問題紛紛擾擾,如果父程序/執行緒先於子程序/執行緒終止,系統會做什麼處理呢?反之,如果子程序/執行緒先於父程序/執行緒終止,系統又會做什麼處理呢?下面是我個人平時在筆記上做的一些象徵性的總結,如果有疑問之處,大可提出,我一直認為懷疑是人類進步的根本所在。

一、執行緒
Linux執行緒建立函式為pthread_create(),預設規則是誰建立子執行緒,誰就要負責子執行緒的資源回收,當父執行緒退出後,子執行緒也隨著退出。所以,一般情況下,父執行緒退出時都要確保子執行緒已經退出,所以會使用pthread_join()函式阻塞等待子執行緒的退出訊號/標識。
pthread_detach(threadid)函式的功能是使執行緒ID為threadid的執行緒處於分離狀態(可以為非父子關係),一旦執行緒處於分離狀態,該執行緒終止時底層資源立即被回收;否則終止子執行緒的狀態會一直儲存佔用系統的資源直到主執行緒呼叫pthread_join(threadid,NULL)獲取執行緒的退出狀態。被建立的子執行緒也可以自己分離自己,子執行緒呼叫pthread_detach(pthread_self())就是分離自己,因為pthread_self()這個函式返回的就是自己本身的執行緒ID。
1)父執行緒先於子執行緒終止

父執行緒先於子執行緒,則子執行緒為異常退出 ,那肯定沒有使用阻塞非分離函式pthread_join,分2種情況:
a)子執行緒已與父執行緒分離,如呼叫執行緒分離函式pthread_detach,則資源被自動回收釋放。
b)子執行緒未與父執行緒分離,則資源無法釋放,造成了資源浪費和系統臃腫(這種情況,我看有些資料上說系統也能自動釋放子執行緒的資源,如關閉描述符,釋放記憶體空間等等,但個人做過一些測試,比如在子執行緒中分配很多空間等,程序退出後,top檢視記憶體狀態時還存在)。
2)子執行緒先於父執行緒終止
也分2種情況:
a)正常情況:子執行緒呼叫了執行緒分離函式ptread_detach(),或父執行緒呼叫了等待執行緒結束函式pthread_join()。
 b)異常情況:如果上面二者都為呼叫,則為子執行緒分配的資源無法得到釋放。

二、程序
一個現有程序可以呼叫fork函式建立一個新程序。由fork建立的新程序被稱為子程序(child process)。fork函式被呼叫一次但返回兩次。兩次返回的唯一區別是子程序中返回0值而父程序中返回子程序ID。
1)父程序先於子程序終止
當父程序先退出時,系統會讓init程序接管子程序,該子執行緒成為了孤兒程序。
2)子程序先於父程序終止
分為2種情況:
a)正常情況:父程序呼叫了wait函式 (非父子程序則用waitpid函式),此時父程序會等待子程序結束。
 b)父程序又沒有呼叫wait函式 (非父子程序則未呼叫waitpid函式),此種情況子程序進入僵死狀態即殭屍程序,並且會一直保持下去直到系統重啟。

子程序處於僵死狀態時,核心只儲存程序的一些必要資訊以備父程序所需。此時子程序始終佔有著資源,同時也減少了系統可以建立的最大程序數。
僵死狀態:一個已經終止、但是其父程序尚未對其進行善後處理(獲取終止子程序的有關資訊,釋放它仍佔有的資源)的程序被稱為僵死程序(zombie)。ps命令將僵死程序的狀態列印為Z 。

相關推薦

執行確保執行退出之後 執行退出

 Linux下程式設計,執行緒、程序退出順序問題紛紛擾擾,如果父程序/執行緒先於子程序/執行緒終止,系統會做什麼處理呢?反之,如果子程序/執行緒先於父程序/執行緒終止,系統又會做什麼處理呢?下面是我個人平時在筆記上做的一些象徵性的總結,如果有疑問之處,大可提出,我一直認

關於執行自動建立的Looper的思考:執行Looper的輪詢死迴圈為何沒有阻塞執行

Android中UI執行緒會自動給我們建立一個looper,但是looper中的loop方法是個死迴圈.為什麼我們在UI執行緒中寫的程式碼為何都能順利執行?為什麼沒有引起ANR呢? Looper的部分原始碼: /** * Initial

關於執行執行過程,業務邏輯出現未知異常導致執行中斷問題反思

關於執行緒池執行過程中,業務邏輯出現未知異常導致執行緒中斷問題反思 最近在專案研發中的關於執行緒池應用過程中由於業務邏輯異常導致的執行緒中斷,但程式未中斷導致的髒資料問題  話不多說,在最近最新的一個版本釋出過程中,業務需要,我們要定期去給客戶預留出可用的資源資料,提供客戶使用,在

Android UI 執行Loop.loop()死迴圈為啥沒有阻塞執行

要完全徹底理解這個問題,需要準備以下4方面的知識:Process/Thread,Android Binder IPC,Handler/Looper/MessageQueue訊息機制,Linux pipe/epoll機制。總結一下樓主主要有3個疑惑:1.Android中為什麼主執行緒不會因為Looper.loo

3、jq動畫執行過程不讓重複點選(即執行完動畫後點擊)

$(".btnoff").click(function(){ var offbtnStatus = false;//初始化狀態,給狀態false,不讓連續點選 if(offbtnStatus){//如果狀態為真,說明函式未執行完,return跳出 return;

robot framework程式執行過程,遇到點選事件之後,未出現點選之後的效果(求解)

1.click Element操作,在實際過程中偶然會出現,日誌顯示已點選成功,但是實際自動化頁面,沒有點選成功之後的操作 現象: 現象描述:程式執行到點選側邊欄的【人員資訊】之後,日誌顯示已經點選成功,但是報錯截圖可以看到並沒有相對應點選成功之後,出現的人員資訊頁面,故判斷找不到開啟頁面 測試中其他的

AngularJs,如何在render完成之後執行Js指令碼

AngularJs和Jquery的有什麼不同? Jquery的主要目的是簡化Js編寫,專注於瀏覽器跨平臺,主要用來操作DOM. AngularJs主要關注Html資料的獲取和呈現,以及應對日益複雜的Web應用需求,使得開發龐大的Web應用能夠更加容易。 Angular

Java執行之捕獲執行的異常

在某些場景下,我們經常需要使用多執行緒來執行任務提高效能,但是我們知道正常的主執行緒是無法處理子執行緒的異常的,一旦出現異常就會傳播到控制檯。這個時候我們需要線上程裡面處理異常怎麼辦呢,我們可以使用E

Android執行之(一)View.post()原始碼分析——在執行更新UI

       提起View.post(),相信不少童鞋一點都不陌生,它用得最多的有兩個功能,使用簡便而且實用:        1)在子執行緒中更新UI。從子執行緒中切換到主執行緒更新UI,不需要額外new一個Handler例項來實

Java執行Synchronized簡介和Static Synchronized的區別

在進行Java開發時,多執行緒的開發是經常會使用的。首先會問一個小問題啊,在Java中有幾種方法可以建立一個執行緒? 我給的答案是3種。(如果還有其他的請留言告訴我哈。) 1、建立直接繼承自Thread類建立執行緒子類。   步驟如下:a 定義一個子類,同時

Android執行模型--在執行更新UI

       Android是支援多執行緒的。主執行緒也稱UI執行緒,子執行緒也稱工作執行緒。一般耗時操作在子執行緒中進行,更新UI操作在主執行緒中進行。在主執行緒中執行耗時操作容易發生ANR錯誤,即應用程式無響應。而Android中又規定只有建立UI的執行緒

執行的佇列不一定需要執行安全

兩個執行緒,主執行緒中update update(){   while(queue.count >0){     //process....     queue.pop()   } }   子執行緒中: queue.enqueue(data)   這樣做是沒有問

junit測試和main方法執行遇到的問題

利用Junit測試多執行緒時經常遇到任務執行不完就會停止,下面是我的任務執行緒類: package timerTest; import java.io.BufferedReader; import java.io.BufferedWriter; import java.i

Android執行執行傳送資訊

主要用到了Handler類,Looper類和Message類 先介紹下這幾個類 Looper類,是用來為一個執行緒開啟一個訊息佇列,預設情況下Android下新開啟的執行緒沒有開啟訊息佇列的,除了主執行緒外,主執行緒系統會預設為其開啟一個訊息佇列;looper是通過MessageQueu

如何在執行執行注入bean

轉:https://segmentfault.com/q/1010000007172414?_ea=1264473 如何在多執行緒中注入bean?!​​​​​​​ 問題對人有幫助,內容完整,我也想知道答案0問題沒有實際價值,缺少關鍵內容,沒有改進餘地 前幾天,在sf這裡也提過這個問題,但

謹慎使用執行的fork

前言 在單核時代,大家所編寫的程式都是單程序/單執行緒程式。隨著計算機硬體技術的發展,進入了多核時代後,為了降低響應時間,重複充分利用多核cpu的資源,使用多程序程式設計的手段逐漸被人們接受和掌握。然而因為建立一個程序代價比較大,多執行緒程式設計的手段也就逐漸被人們認可和喜愛了。 記得在我剛

執行的鎖

樂觀鎖和悲觀鎖 樂觀鎖和悲觀鎖是在資料庫中引入的名詞,但是在併發包鎖裡面也引入了類似的思想,所以這裡還是有必要講解一下。 悲觀鎖指對資料被外界修改持保守的態度,認為資料很容易就會被其他執行緒修改,所以在資料被處理前就先對資料加鎖,並在整個資料處理過程中,使資料處於鎖定狀態,悲觀鎖的實現往往依靠資料庫

QT執行,物件訊號與槽連線不上的解決辦法

1、在接收者建立執行緒中,把接收者移動到主執行緒中: pReceiverObj->moveToThread(QApplication::instance()->thread()); 2、這樣傳送訊號的時候,就會在主執行緒事件佇列處理中來處理了。 把connect的最

執行的訊號機制--sigwait 函式

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!