进程创建和结束

所有的进程都是由其他进程创建(除了 pid 为 0 号的 idle 进程),pid 号为 1 的 init
进程是系统启动后运行的第一个进程,是所有进程的父进程,init 进程会初始化一部分系统服务,创建其他进程。

子进程结束后,它的父进程要回收它的资源,否则就会成为僵尸进程 。

如果父进程先结束,子进程会被 init 进程收养,称为孤儿进程。

“ps -el”查看进程状态 PID 为进程号,PPID 为此进程的父进程号

getpid() 
getpid():获取进程 PID, #include <sys/types.h> #include <unistd.h> pid_t
getpid(void);//获取此进程 PID pid_t getppid(void);//获取父进程 PID 返回值为 PID 号。
 fork()
fork():系统调用,创建一个进程, #include <unistd.h> pid_t fork(void);
//调用成功父进程返回子进程号,子进程返回 0,失败返回-1。 /*第一次调用 fork()进程 2531 创建子进程 2532;第二次 fork(),进程
2531 创建子进程 2533, 进程 2532 创建 2534*/ #include <stdio.h> #include <unistd.h>
#include <stdlib.h> int main(int argc, const char *argv[]) { pid_t pid; int i;
for(i=0;i<2;i++) { pid=fork(); if(pid>0) { printf("进程%d\n",getpid()); }else
if(pid == 0) { printf("进程%d\n",getpid()); } } return 0; }
exit() 
exit():进程终止可使用, #include <stdlib.h> void exit(int status);
/*函数功能:调用各终止处理程序进行清理退出,通过参数保存退出状态,调用_exit 进入内核态,向父进程发送信号 SIGCHLD,子进程终止。
参数含义:退出状态,如 EXIT_SUCCESS 和 EXIT_FAILURE。*/
 wait(),waitpid()
wait(),waitpid():回收子进程可使用, #include <sys/types.h> #include <sys/wait.h> pid_t
wait(int *status); pid_t waitpid(pid_t pid, int *status, int options); 参数含义:
/*status: 子进程的退出状态,可以用以下几个宏判断状态: WIFEXITED(status) //判断子进程是否正常结束
WEXITSTATUS(status) //获取子进程返回值,1为正常,0为失败 WIFSIGNALED(status) //判断子进程是否被信号结束
WTERMSIG(status) //获取结束子进程的信号类型 /* pid: waitpid()中的参数, pid=-1 时,表示等待任一子进程退出,
pid > 0 等待 pid 号子进程退出。 options: waitpid()中的参数,控制 waitpid()。 返回值:若成功则为进程
ID,若出错则为-1 。 */ #include <stdio.h> #include <unistd.h> #include <stdlib.h>
#include <sys/wait.h> void exit_status(pid_t p ,int s); int main(int argc,
const char *argv[]) { pid_t pid,spid; int s_son=-1; pid = fork(); if(pid<0) {
perror("fork"); return 1; }else if(pid == 0) { printf("子进程 %d\n",getpid());
sleep(1); exit(EXIT_FAILURE); //exit(EXIT_SUCCESS);//返回 0 }else if(pid >0) {
printf("父进程 %d\n",getpid()); //sleep(1);//等待子进程退出 spid =
wait(&s_son);//获取子进程退出状态 exit_status(spid,WEXITSTATUS(s_son));//打印 } return 0;
} /** 打印退出状态 */ void exit_status(pid_t p ,int s) { switch (s) { case 0:
printf("子进程--%d--退出状态: EXIT_SUCCESS\n",p); break; case 1:
printf("子进程--%d--退出状态: EXIT_FAILURE\n",p); break; default: printf("other\n");
break; } }
exec 函数族
用 fork 函数创建子进程后,子进程往往要调用一种 exec 函数以执行另一个程序,该子进程被新的程序 替换,改变地址空间,进程映像和一些属性,但是
pid 号不变。 execve(): #include <unistd.h> int execve(const char *filename, char
*const argv[], char *const envp[]); /* 参数含义: filename:路径名,表示载入进程空间的新程序路径。
argv[]:命令行参数,argv[0]为命令名。 envp[]:新程序的环境变量。 返回值:成功时不会返回,使用时不用检查返回值,可通过 errno 检查。
以下函数都是根据 execve 实现: */ int execl(const char *path, const char *arg, .../* (char
*) NULL */); int execlp(const char *file, const char *arg, .../* (char *) NULL
*/); int execle(const char *path, const char *arg, .../*, (char *) NULL, char *
const envp[] */); int execv(const char *path, char *const argv[]); int
execvp(const char *file, char *const argv[]); int execvpe(const char *file,
char *const argv[],char *const envp[]);

#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include
<sys/wait.h> void exit_status(pid_t p ,int s); int main(int argc, const char
*argv[]) { pid_t pid,spid; int s_son=-1; pid = fork(); if(pid<0) {
perror("fork"); return 1; }else if(pid == 0) { printf("子进程 %d\n",getpid());
if(-1 == execl("/bin/ls","ls","./",NULL))//ls 进程替换子进程 { perror("execl");
exit(EXIT_FAILURE); } exit(EXIT_SUCCESS);//返回 0 } else if(pid >0) { printf("父进程
%d\n",getpid()); spid = wait(&s_son);//获取子进程退出状态
exit_status(spid,WEXITSTATUS(s_son));//打印 }while(1) { printf("hello\n");
sleep(2); } return 0; }/** 打印退出状态 */ void exit_status(pid_t p ,int s) { switch
(s) { case 0: printf("子进程--%d--退出状态: EXIT_SUCCESS\n",p); break; case 1:
printf("子进程--%d--退出状态: EXIT_FAILURE\n",p); break; default: printf("other\n");
break; } }
守护进程

1.什么是守护进程? 守护进程运行在后台,不跟任何控制终端关联。

2.怎么创建一个守护进程?

有俩个基本要求:1.必须作为我们init进程的子进程⒉.不跟控制终端交互。

1.使用fork函数创建一个新的进程,然后让父进程使用exit函数直接退出(必须要的)

2.调用setsid函数。(必须要的)

3.调用chdir函数,将当前的工作日录改成根目录,增强程序的健壮性。(不是必须要的)

4.重设我们umask文件掩码,增强程序的健壮性和灵活性(不是必须要的)

5.关闭文件描述符,节省资源(不是必须要的)

6.执行我们需要执行的代码(必须要的)
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include
<sys/stat.h> #include <stdlib.h> int main(vold) { pid_t pid; //步骤一:创建一个新的进程 pid
= fork(); /父进程直接退出 if(pid > 0) { exit(0); } if(pld == 0) {
//步骤2:调用setsid函数摆脱控制终端 setsid(); //步骤3:更改工作目录 chdir("/"); //步骤4:重新设置umask文件掩码
umask(0); //步骤5:关闭012三个文件描述符 close(0); close(1); close(2); //步骤6:执行我们要执行的代码
while(1) { } } return 0; }

技术
下载桌面版
GitHub
百度网盘(提取码:draw)
Gitee
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:766591547
关注微信