目录
一、孤儿进程
定义:孤儿进程是指那些其父进程已经结束,但它们依然在运行的进程
创建一个孤儿进程:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> int main() { pid_t pid = fork(); // 创建子进程 if (pid < 0) { // fork失败 perror("fork"); exit(EXIT_FAILURE); } if (pid == 0) { // 子进程 printf("Child process: PID=%d, PPID=%d\n", getpid(), getppid()); // 暂停子进程,以便父进程有足够时间退出 sleep(10); // 父进程退出后,子进程成为孤儿进程 printf("Child process (orphan): PID=%d, PPID=%d\n", getpid(), getppid());//父进程退出后查看子进程的父进程id和子进程id } else { // 父进程 sleep(1); printf("Parent process: PID=%d\n", getpid());//父进程ID // 父进程退出 exit(EXIT_SUCCESS); } return 0; }
主要进程标识:
进程号:PID(process id)
父进程号:PPID(parent process id)
进程组号:PGID,进程组:若干个进程的集合称之为进程组,默认情况下,新创建的进程会进程父进程的进程组ID
会话组号:SID,会话组:若干个进程组的集合称之为会话组,默认情况下,新创建的进程会继承父进程的会话ID
二、僵尸进程
定义: 僵尸进程(Zombie Process)是指那些已经完成执行但仍然存在于系统中的进程。这些进程已经终止,但它们的进程控制块(PCB)还未被父进程读取和清理。
创建一个僵尸进程:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main() { pid_t pid = fork(); if (pid < 0) { perror("fork"); exit(EXIT_FAILURE); } if (pid == 0) { // 子进程 printf("Child process: PID=%d\n", getpid()); // 子进程终止,但父进程故意不调用wait()来清理 exit(EXIT_SUCCESS); } else { // 父进程 printf("Parent process: PID=%d\n", getpid()); // 父进程故意不调用wait(),等待子进程成为僵尸 sleep(5); // 让子进程有时间成为僵尸 printf("Parent process exiting\n"); // 父进程退出 exit(EXIT_SUCCESS); } return 0; }
三、守护进程(精灵进程)
定义:守护进程(精灵进程)(Daemon Process)是指那些在后台运行的进程,通常不与用户直接交互。精灵进程在系统启动时启动,持续运行,并在系统关闭时退出。它们通常用于提供系统服务或进行系统管理任务。
创建一个精灵进程:
1、创建孤儿进程 pid = fork() if(pid > 0) exit(0); 2、创建新的会话组:让孤儿进程成为会话组组长 可以让子进程完全独立,脱离其他兄弟,亲缘进程的控制 setsid();//创建新会话,当前进程变为会话组组长 3、修改进程的工作路径(运行目录),比如:家目录,根目录 chdir(新路径) 4、重设文件权限掩码 umask(0); 5、关闭所有的文件描述符:从父进程得到的文件描述符用不到,全部关闭 getdtablesize() == max + 1 for(int i = 0;i < getdtablesize ;i++) close(i);
实现代码:
//创建一个守护进程 #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<wait.h> #include<sys/stat.h> #include<sys/types.h> #include<fcntl.h> int main(int argc, const char *argv[]) { //1、创建一个孤儿进程 pid_t pid=fork(); if(pid>0) exit(0); //2、创建一个会话组 setsid(); //3、修改工作路径 chdir("/home/ubuntu/test"); //4、重设文件权限掩码 umask(0); //5、关闭其他文件描述符,包括终端文件 for(int i=0;i<getdtablesize();i++) close(i); //守护进程创建成功 //用守护进程写入数据进入文件 int fd = open("1.txt",O_WRONLY|O_TRUNC|O_CREAT,0664); char *p="hello world"; while(1) { write(fd,p,10); sleep(1); } close(fd); return 0; }