进程重要API
1. 获取进程ID
pid_t getpid()
用于获取当前进程的进程ID。该函数原型为:
pid_t getpid(void);
该函数没有参数,它返回一个 pid_t 类型的值,表示当前进程的进程ID。
pid_t getppid()
用于获取当前进程的父进程的进程ID。该函数原型为:
pid_t getppid(void);
该函数没有参数,它返回一个 pid_t 类型的值,表示当前进程的父进程的进程ID。
2. 进程创建
2.1 API
pid_t fork(void)
是 Linux 操作系统中的一个函数,用于创建一个新的进程。该函数原型为:
pid_t fork(void);
该函数不需要任何参数,并返回一个
pid_t
类型的值。当进程被成功创建时,该函数在原来的进程(父进程)中返回新进程的进程标识符(PID),在新进程中返回0。
如果进程创建失败,则该函数会返回一个负值。
注意
fork()
会使得进程本身被复制,因此被创建出来的子进程和父进程几乎是一模一样的。- 子进程会从
fork()
返回值后的下一条逻辑语句开始运行。 - 父子进程的执行次序是随机的,无法判断谁先谁后,除非使用特殊机制同步它们。
- 父子进程是相互独立、互不影响的。
2.2 父子进程共同点
- 实际 UID 和 GID,以及有效 UID 和 GID。
- 所有的环境变量
- 进程组ID和会话ID
- 当前工作路径,除非用 chdir( ) 进行修改。
- 打开的文件
- 整个内存空间,包括栈、堆、数据段、代码段、标准IO的缓冲区等等。
- 信号响应函数
2.3 父子进程区别
- 进程的PID
- 挂起的信号
- 记录锁
2.4 示例代码
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
pid_t pid;
// 使用 fork() 函数创建一个新的进程
pid = fork();
// 如果 pid 为 0,则表示当前进程为新创建的进程
if (pid == 0) {
printf("In child process\n");
}
// 如果 pid 大于 0,则表示当前进程为原来的进程(父进程)
else if (pid > 0) {
printf("In parent process\n");
}
// 如果 pid 小于 0,则表示创建进程失败
else {
printf("Failed to create new process\n");
}
return 0;
}
3. exec函数簇
3.1 第一组函数簇
Linux 的 exec 函数簇是一组函数,它们用于替换当前进程的程序段。exec 函数簇包括多个不同的函数,每个函数都有不同的参数和功能。
execl()\execv()\execle
函数用于在当前进程中执行一个新程序,并将该程序替换当前进程。这些函数原型为:
int execl(const char *path, const char *arg, ...);
int execv(const char *path, char * const argv[]);
int execle(const char *path, const char *arg, ..., char *const envp[]);
这些函数的参数:
path
:一个字符串,表示要执行的程序的路径。arg
:一个字符串,表示执行程序时传递给它的第一个参数。argv[]
:表示传递给程序的参数数组。第一个参数必须是程序名,接下来的参数可以是任意数量的字符串。...
:可变长度的参数列表,包含该程序的其余命令行参数。char *const envp[]
:一个指向环境变量的指针数组。这些函数返回一个整型值,如果执行成功,则返回值为 0;如果执行失败,则返回一个非零值。