進(jìn)程的創(chuàng)建是Linux系統(tǒng)編程中的重要概念之一。在本節(jié)中,我們將介紹進(jìn)程的創(chuàng)建、獲取進(jìn)程ID和父進(jìn)程ID、進(jìn)程共享、exec函數(shù)族、wait和waitpid等相關(guān)內(nèi)容。
1. 進(jìn)程的創(chuàng)建
在Linux系統(tǒng)中,進(jìn)程的創(chuàng)建使用fork()
系統(tǒng)調(diào)用。fork()
系統(tǒng)調(diào)用會(huì)創(chuàng)建一個(gè)與當(dāng)前進(jìn)程相同的子進(jìn)程,子進(jìn)程會(huì)復(fù)制父進(jìn)程的所有資源,包括代碼、數(shù)據(jù)和文件描述符等。
1.1 函數(shù)原型和返回值
fork()
函數(shù)的原型如下:
#include <unistd.h>
pid_t fork(void);
fork()
函數(shù) 沒(méi)有任何參數(shù) ,它的返回值是一個(gè)pid_t
類型的整數(shù)。具體解釋如下:
- 如果調(diào)用成功,
fork()
函數(shù)會(huì)在父進(jìn)程中返回子進(jìn)程的PID(子進(jìn)程ID),在子進(jìn)程中返回0。 - 如果調(diào)用失敗,
fork()
函數(shù)會(huì)返回-1,并設(shè)置errno
來(lái)指示錯(cuò)誤類型。
1.2 函數(shù)示例
代碼示例如下:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
pid_t pid = fork();
if (pid == -1) {
printf("Failed to fork a new process.\n");
return 1;
} else if (pid == 0) {
printf("This is the child process.\n");
} else {
printf("This is the parent process.\n");
}
return 0;
}
上述代碼中,fork()
系統(tǒng)調(diào)用會(huì)返回兩次,分別在父進(jìn)程和子進(jìn)程中返回。通過(guò)判斷返回值,我們可以區(qū)分父進(jìn)程和子進(jìn)程,并執(zhí)行不同的代碼邏輯。
2. 獲取進(jìn)程ID和父進(jìn)程ID
在Linux系統(tǒng)中,可以使用getpid()
和getppid()
系統(tǒng)調(diào)用來(lái)獲取當(dāng)前進(jìn)程的ID和父進(jìn)程的ID。
2.1 函數(shù)原型和返回值
getpid()
和getppid()
函數(shù)的原型如下:
#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void);
pid_t getppid(void);
這兩個(gè)函數(shù)都 沒(méi)有任何參數(shù) ,它們的返回值都是一個(gè)pid_t
類型的整數(shù)。具體解釋如下:
-
getpid()
函數(shù)返回調(diào)用進(jìn)程的進(jìn)程ID(PID)。 -
getppid()
函數(shù)返回調(diào)用進(jìn)程的父進(jìn)程的進(jìn)程ID(PPID)。
2.2 函數(shù)示例
代碼示例如下:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
pid_t pid = getpid();
pid_t ppid = getppid();
printf("Process ID: %d\n", pid);
printf("Parent Process ID: %d\n", ppid);
return 0;
}
3. exec函數(shù)族
在Linux系統(tǒng)中,exec()
函數(shù)族可以用于將當(dāng)前進(jìn)程替換為新的程序。exec()
函數(shù)族包括execl()
、execv()
、execle()
、execve()
等函數(shù)。這些函數(shù)可以根據(jù)不同的參數(shù)形式來(lái)執(zhí)行不同的替換方式。
3.1 exec()
函數(shù)族的常見(jiàn)成員:
-
int execl(const char *path, const char *arg, ...);
- 參數(shù)
path
是要執(zhí)行的新程序的路徑。 - 參數(shù)
arg
是一個(gè)字符串,表示新程序的第一個(gè)參數(shù)。 - 可變參數(shù)列表是新程序的其他參數(shù),必須以
NULL
結(jié)束。 - 函數(shù)執(zhí)行成功時(shí)不會(huì)返回,如果返回則表示執(zhí)行失敗。
- 參數(shù)
-
int execv(const char *path, char *const argv[]);
- 參數(shù)
path
是要執(zhí)行的新程序的路徑。 - 參數(shù)
argv
是一個(gè)字符串?dāng)?shù)組,表示新程序的參數(shù)列表,最后一個(gè)元素必須是NULL
。 - 函數(shù)執(zhí)行成功時(shí)不會(huì)返回,如果返回則表示執(zhí)行失敗。
- 參數(shù)
-
int execle(const char *path, const char *arg, ..., char *const envp[]);
- 參數(shù)
path
是要執(zhí)行的新程序的路徑。 - 參數(shù)
arg
是一個(gè)字符串,表示新程序的第一個(gè)參數(shù)。 - 可變參數(shù)列表是新程序的其他參數(shù),必須以
NULL
結(jié)束。 - 參數(shù)
envp
是一個(gè)字符串?dāng)?shù)組,表示新程序的環(huán)境變量列表,最后一個(gè)元素必須是NULL
。 - 函數(shù)執(zhí)行成功時(shí)不會(huì)返回,如果返回則表示執(zhí)行失敗。
- 參數(shù)
-
int execvp(const char *file, char *const argv[]);
- 參數(shù)
file
是要執(zhí)行的新程序的文件名。 - 參數(shù)
argv
是一個(gè)字符串?dāng)?shù)組,表示新程序的參數(shù)列表,最后一個(gè)元素必須是NULL
。 - 函數(shù)執(zhí)行成功時(shí)不會(huì)返回,如果返回則表示執(zhí)行失敗。
- 參數(shù)
這些函數(shù)在執(zhí)行成功時(shí)不會(huì)返回,而是直接將當(dāng)前進(jìn)程替換為新程序。如果返回,則表示執(zhí)行失敗,可以根據(jù)返回值來(lái)判斷錯(cuò)誤類型。
exec()
函數(shù)族可以用于在當(dāng)前進(jìn)程中加載和執(zhí)行新程序,可以實(shí)現(xiàn)程序的動(dòng)態(tài)切換和功能擴(kuò)展。一般情況下,exec()
函數(shù)族會(huì)在調(diào)用fork()
函數(shù)創(chuàng)建子進(jìn)程后使用,以替換子進(jìn)程的代碼和數(shù)據(jù)。
3.2 函數(shù)示例
代碼示例如下:
#include <stdio.h>
#include <unistd.h>
int main() {
printf("Before exec()\n");
execl("/bin/ls", "ls", "-l", NULL);
printf("After exec()\n");
return 0;
}
上述代碼中,execl()
函數(shù)會(huì)將當(dāng)前進(jìn)程替換為ls -l
命令。execl()
函數(shù)的第一個(gè)參數(shù)是要執(zhí)行的程序路徑,后續(xù)參數(shù)是傳遞給新程序的命令行參數(shù)。
4. wait和waitpid
在Linux系統(tǒng)中,父進(jìn)程可以使用wait()
或waitpid()
系統(tǒng)調(diào)用等待子進(jìn)程的結(jié)束。這些系統(tǒng)調(diào)用會(huì)阻塞父進(jìn)程的執(zhí)行,直到子進(jìn)程結(jié)束。
4.1 函數(shù)解釋
wait()
和waitpid()
是用于等待子進(jìn)程結(jié)束并獲取子進(jìn)程的退出狀態(tài)的函數(shù)。
-
pid_t wait(int *status);
- 函數(shù)會(huì)掛起當(dāng)前進(jìn)程,直到一個(gè)子進(jìn)程結(jié)束。
- 如果成功等到子進(jìn)程結(jié)束,函數(shù)會(huì)返回子進(jìn)程的進(jìn)程ID。
- 參數(shù)
status
是一個(gè)指向整型的指針,用于存儲(chǔ)子進(jìn)程的退出狀態(tài)信息。 - 如果調(diào)用失敗,函數(shù)會(huì)返回-1。
-
pid_t waitpid(pid_t pid, int *status, int options);
- 函數(shù)會(huì)掛起當(dāng)前進(jìn)程,直到指定的子進(jìn)程結(jié)束。
- 參數(shù)
pid
指定要等待的子進(jìn)程的進(jìn)程ID。 - 參數(shù)
status
是一個(gè)指向整型的指針,用于存儲(chǔ)子進(jìn)程的退出狀態(tài)信息。 - 參數(shù)
options
是一個(gè)整型值,用于指定等待的選項(xiàng)。 - 如果調(diào)用失敗,函數(shù)會(huì)返回-1。
wait()
和waitpid()
函數(shù)的返回值是子進(jìn)程的進(jìn)程ID,如果調(diào)用失敗,則返回-1。通過(guò)參數(shù) status
可以獲取子進(jìn)程的退出狀態(tài)信息,包括退出碼、終止信號(hào)等。
waitpid()
函數(shù)相比于wait()
函數(shù)更加靈活,可以通過(guò)參數(shù) pid
和 options
控制等待的子進(jìn)程。
其中,pid
的取值可以是:
-
-1
:等待任意子進(jìn)程。 -
0
:等待與當(dāng)前進(jìn)程組ID相同的子進(jìn)程。 - 具體的子進(jìn)程ID:等待指定的子進(jìn)程。
options
參數(shù)可以通過(guò)位掩碼的方式指定多個(gè)選項(xiàng),常用的選項(xiàng)有:
-
WNOHANG
:非阻塞方式,如果沒(méi)有子進(jìn)程結(jié)束,立即返回。 -
WUNTRACED
:也會(huì)返回已經(jīng)停止的子進(jìn)程的狀態(tài)。 -
WCONTINUED
:也會(huì)返回已經(jīng)繼續(xù)運(yùn)行的子進(jìn)程的狀態(tài)。
wait()
和waitpid()
函數(shù)可以用于處理子進(jìn)程的退出狀態(tài),釋放子進(jìn)程的資源,并進(jìn)行進(jìn)程間的同步。在使用這兩個(gè)函數(shù)時(shí),需要注意處理錯(cuò)誤情況和避免僵尸進(jìn)程的產(chǎn)生。
4.2 函數(shù)示例
代碼示例如下:
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main() {
pid_t pid = fork();
if (pid == -1) {
printf("Failed to fork a new process.\n");
return 1;
} else if (pid == 0) {
printf("This is the child process.\n");
} else {
wait(NULL);
printf("This is the parent process.\n");
}
return 0;
}
上述代碼中,父進(jìn)程使用wait(NULL)
系統(tǒng)調(diào)用等待子進(jìn)程的結(jié)束。wait()
系統(tǒng)調(diào)用會(huì)阻塞父進(jìn)程的執(zhí)行,直到子進(jìn)程結(jié)束。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-654743.html
總結(jié)
-
fork()
函數(shù):用于創(chuàng)建子進(jìn)程,返回值不同表示在不同的進(jìn)程中執(zhí)行。 -
exec()
函數(shù)族:用于在當(dāng)前進(jìn)程中加載和執(zhí)行新程序,可以實(shí)現(xiàn)程序的動(dòng)態(tài)切換和功能擴(kuò)展。-
execl()
:接受可變參數(shù)的形式,參數(shù)以字符串形式傳遞。 -
execle()
:接受可變參數(shù)的形式,同時(shí)傳遞環(huán)境變量。 -
execvp()
:接受參數(shù)數(shù)組的形式,參數(shù)以字符串?dāng)?shù)組形式傳遞。
-
-
wait()
和waitpid()
函數(shù):用于等待子進(jìn)程結(jié)束并獲取子進(jìn)程的退出狀態(tài)。-
wait()
:等待任意子進(jìn)程結(jié)束。 -
waitpid()
:可以指定等待的子進(jìn)程。 - 通過(guò)參數(shù)
status
可以獲取子進(jìn)程的退出狀態(tài)信息。 - 可以通過(guò)
options
參數(shù)控制等待的選項(xiàng),如非阻塞方式等。 - 需要注意處理錯(cuò)誤情況和避免僵尸進(jìn)程的產(chǎn)生。
-
這些函數(shù)和系統(tǒng)調(diào)用可以用于進(jìn)程的創(chuàng)建、執(zhí)行和等待,實(shí)現(xiàn)進(jìn)程間的同步和協(xié)作。通過(guò)這些函數(shù),可以實(shí)現(xiàn)進(jìn)程的動(dòng)態(tài)切換、功能擴(kuò)展和資源釋放。同時(shí),需要注意處理錯(cuò)誤情況,避免產(chǎn)生僵尸進(jìn)程和資源泄漏的問(wèn)題。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-654743.html
到了這里,關(guān)于【Linux操作系統(tǒng)】深入探索Linux進(jìn)程:創(chuàng)建、共享與管理的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!