exec簡介:
exec家族的函數(shù),用來運(yùn)行新的進(jìn)程替換當(dāng)前的進(jìn)程。執(zhí)行后,新進(jìn)程加載到內(nèi)存,父進(jìn)程的靜態(tài)變量在新的進(jìn)程中當(dāng)然是不可見。新進(jìn)程可以繼承父進(jìn)程的句柄和環(huán)境變量,用戶組。
示例
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int g_value = 0;
int main(int argc, char **argv)
{
if (argc > 1 && strcmp(argv[1], "child") == 0) {
printf("child g_value = %d\n", g_value);
return 0;
}
g_value = 1;
printf("father g_value = %d\n", g_value);
int fd = open("/root/source/test.txt", O_RDWR);
printf("father fd = %d\n", fd);
dup2(fd, 1);
close(fd);
execl("/root/source/cmd", "cmd", "child", NULL);
printf("run child failed\n");
return 0;
}
如上代碼編譯一個(gè)cmd的二進(jìn)制,執(zhí)行cmd命令,
1、父進(jìn)程將g_value 賦值為1,子進(jìn)程中g(shù)_value 依然為0,子進(jìn)程不會繼承父進(jìn)程的變量。
2、將標(biāo)準(zhǔn)輸出的句柄綁定到/root/source/test.txt句柄。子進(jìn)程的句柄依然指向/root/source/test.txt,子進(jìn)程可以繼承父進(jìn)程的句柄。
root@yisu-66a113137e504:~/source# ./cmd
father g_value = 1
father fd = 3
root@yisu-66a113137e504:~/source#
root@yisu-66a113137e504:~/source# cat test.txt
child g_value = 0
這里順帶提一下fork,fork功能是創(chuàng)建一個(gè)新的進(jìn)程,子進(jìn)程獲得父進(jìn)程代碼段和數(shù)據(jù)段的副本(雖然在現(xiàn)代系統(tǒng)中,通常使用寫時(shí)復(fù)制技術(shù)來優(yōu)化內(nèi)存使用)。子進(jìn)程繼承父進(jìn)程的資源限制(如文件大小限制、CPU 時(shí)間限制等)。
fork和execv的組合可實(shí)現(xiàn)子進(jìn)程的管理,如fork創(chuàng)建一個(gè)新的進(jìn)程,設(shè)置它的uid,gid后,再執(zhí)行execv切換新進(jìn)程替換當(dāng)前進(jìn)程。
android service啟動
android service啟動,使用到了fork 和 execv:
Result<void> Service::Start() {
//....
pid = fork();
if (pid == 0) {
RunService(...); // 其中執(zhí)行 execv 加載新的程序,并設(shè)
}
}