今天执行strace
的时候发现,不管哪个进程最后都会调用exit_group
,就打算总结一下进程退出相关的系统调用。
,查阅资料后发现有以下。
1.
exit()
:
exit()
是标准 C 库中的函数,用于终止当前进程。void exit(int status);
exit()
函数将终止当前进程,并将退出状态 status
返回给父进程。exit()
函数将执行一系列清理操作,包括关闭文件描述符、刷新缓冲区以及执行通过 atexit()
注册的终止处理程序。EXIT_SUCCESS
和 EXIT_FAILURE
宏来表示进程的成功或失败状态。2. _exit()
:
_exit()
是一个系统调用,用于立即终止当前进程,不执行清理操作。void _exit(int status);
_exit()
函数将立即终止当前进程,并将退出状态 status
返回给父进程。_exit()
不会执行清理操作,包括不会关闭文件描述符、不会刷新缓冲区,也不会执行终止处理程序。3. atexit()
:
atexit()
函数用于注册在进程终止时自动执行的终止处理程序。int atexit(void (*function)(void));
atexit()
函数并传递一个函数指针,可以注册一个终止处理程序。atexit()
来注册多个终止处理程序,它们将按照注册的相反顺序执行。4. exit_group()
:
exit_group()
是 Linux 特定的系统调用,用于终止整个进程组中的所有进程,包括当前进程。void exit_group(int status);
exit_group()
将立即终止当前进程组中的所有进程,包括当前进程。exit_group()
不执行清理操作,也不返回到调用进程,因为它会终止整个进程组。这些 API 提供了不同的方式来控制进程的退出和清理操作。
接下来演示一下网上找到的的示例程序
exit()
终止进程c#include <stdio.h>
#include <stdlib.h>
int main() {
printf("This is the main process.\n");
// 调用 exit() 终止当前进程
exit(EXIT_SUCCESS);
// 下面的代码不会被执行
printf("This line will not be printed.\n");
return 0;
}
当程序执行到 exit()
时,当前进程将被终止。因此,printf()
函数后面的代码将不会被执行。
_exit()
终止进程c#include <stdio.h>
#include <unistd.h>
int main() {
printf("This is the main process.\n");
// 调用 _exit() 终止当前进程
_exit(EXIT_SUCCESS);
// 下面的代码不会被执行
printf("This line will not be printed.\n");
return 0;
}
当程序执行到 _exit()
时,当前进程将被立即终止。与 exit()
不同,_exit()
不执行清理操作,直接退出。
atexit()
注册终止处理程序c#include <stdio.h>
#include <stdlib.h>
void cleanup() {
printf("Executing cleanup...\n");
// 执行一些清理操作
}
int main() {
printf("This is the main process.\n");
// 注册终止处理程序
atexit(cleanup);
// 调用 exit() 终止当前进程
exit(EXIT_SUCCESS);
// 下面的代码不会被执行
printf("This line will not be printed.\n");
return 0;
}
cleanup()
函数作为终止处理程序被注册。当进程正常终止时,注册的终止处理程序将被调用,执行一些清理操作。
exit_group()
终止进程组中的所有进程c#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
printf("This is the main process. PID: %d\n", getpid());
// 创建一个子进程
pid_t child_pid = fork();
if (child_pid == 0) {
// 子进程
printf("This is the child process. PID: %d\n", getpid());
// 子进程调用 exit_group() 终止整个进程组
exit_group(EXIT_SUCCESS);
} else if (child_pid > 0) {
// 父进程
printf("This is the parent process. PID: %d\n", getpid());
// 等待子进程终止
int status;
wait(&status);
if (WIFEXITED(status)) {
printf("Child process terminated with exit status: %d\n", WEXITSTATUS(status));
}
} else {
// fork() 失败
perror("fork");
exit(EXIT_FAILURE);
}
// 下面的代码不会被执行
printf("This line will not be printed.\n");
return 0;
}
在这个示例中,主进程创建了一个子进程,并等待子进程终止。子进程调用了 exit_group()
终止整个进程组。当子进程终止后,父进程会检查子进程的退出状态并打印出来。
进程组是进程的集合,通常是由父进程创建,父进程创建子进程并将其加入到自己这个进程组,进程组的PGID就等于父进程自己的PID,子进程初始的PGID也等于父进程的PID,除非子进程创建会话成为另一个会话的领导者,子进程的PGID会变成自己的PID,还有通过setpgid
手动加入到其他进程组。
所以,exit_group
会杀死和这个程序有关的所有进程。s
本文作者:yowayimono
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!