Android守護程序 為什麼要fork()兩次

2021-07-24 10:49:13 字數 1312 閱讀 2333

雖然,我本身很排斥這種做法,有點類似「流氓軟體」的行為,但是還是查詢了資料,大概想了乙個實現的方式,和大家一起分享。

其實,這個問題可以簡單的看作:如何編寫乙個守護程序。

使用c/c++編寫乙個守護程序的.so程式,android端通過jni呼叫。該程序監聽當前的目標程式程序,如果目標程式被kill掉了,再重新start一下,大概的思路就是這樣。偽**如下:

int pid =fork();

if(pid <0

)else

if(pid > 0

)else

if(pid == 0) //

child1}}

這其中,缺少了:

①unmask(),因為從父程序繼承下來了一些東西,所以需要設定一定的許可權進行操作。

②chdir("/")。

③關閉從父程序繼承而來的不需要的檔案描述符,否則就可能造成資源的浪費。

為什麼要進行兩次fork()?

在這段偽**中,進行了兩次fork()操作,其實很多文章在描述守護程序時都只是僅僅的進行了一次fork操作就結束了,這裡我想仔細講一講原因。

首先,setsid()函式的作用。一般而言,父程序和子程序都處在乙個session當中,父程序是session的領頭程序。如果當父程序(領頭程序)被殺死之後,那麼同乙個session中的所有程序都會被殺死,或者成為孤兒程序而被init託管。所以,我們需要讓子程序呼叫setsid(),建立乙個新的session並將自己設定為該session的領頭程序(若領頭程序呼叫setsid()則沒有任何效果)。這樣,如果父程序被kill掉,因為他們並不在乙個session中,所以子程序仍然可以繼續執行。由於session對控制終端的獨占性,程序同時與控制終端脫離。

session中包含了很多東西,如:控制終端、程序組等等。如果我們只fork()一次,將第乙個由父程序建立出的子程序分離出來作為守護程序,一般情況下也是沒有什麼問題的。但是,如果此時通過什麼方式通過此程序建立出了乙個與自己的session相關聯的控制終端,那麼則會產生一定的影響。所以,則有了第二次fork()的意義。第二次fork使用子程序建立出了乙個「孫子程序」,並且我們還是使用第乙個父程序建立出的子程序進行setsid()但它並不是守護程序,該孫子程序進行守護程序相關的操作。這就有效的避免了上文提到的問題的產生,因為子程序建立出了乙個新的session,並且作為該session的領頭程序,同時這個session包含了該孫子程序且它並不是領頭程序。那麼該孫子程序就永遠無法建立出乙個控制終端,也就沒有任何影響。

存在的問題

標籤: 

守護程序, 

android, 

fork(), 

setsid()

守護程序為什麼要fork兩次?

1 呼叫一次fork的作用 第一次fork的作用是讓shell認為這條命令已經終止,不用掛在終端輸入上,還有就是為了後面的setsid服務,因為呼叫setsid函式的程序不能是程序組組長,如果不fork出子程序,則此時的父程序是程序組組長,就無法呼叫setsid。當子程序呼叫完setsid函式之後,...

為什麼要學習程序程式替換?

1 守護程序 父程序先啟動,建立乙個子程序,讓子程序程式替換成為另外乙個程式,實現不同的乙個功能,父子程序會程序通訊,進而完成當子程序異常退出的時候,父程序會重新啟動子程序。守護程序能有效解決子程序異常退出的問題,但是不能解決子程序退出本質,真正需要解決還得程式設計師debug。程序程式替換介面 i...

什麼是守護程序?

守護程序是在後台執行不受終端控制的程序 如輸入 輸出等 一般的網路服務都是以守護程序的方式執行。守護程序脫離終端的主要原因有兩點 1 用來啟動守護程序的終端在啟動守護程序之後,需要執行其他任務。2 如其他使用者登入該終端後,以前的守護程序的錯誤資訊不應出現 由終端上的一些鍵所產生的訊號 如中斷訊號 ...