本片博客的操作均在Linux系统下进行:
进程创建:父进程来创建除一个新的子进程的过程。
父进程想要创建一个函数就需要使用fork()函数或者vfork()函数。
fork()函数; //头文件 #include <unistd.h> //fork()函数原型: pid_t fork(void); //返回值: 从进程中返回0,父进程返回子进程id,出错返回-1; vfork()函数; //头文件: #incldue <unistd.h> //vfork()函数原型: pid_t vfork(void); //返回值: 从子进程中返回0,父进程返回子进程id,出错返回-1;fork()v函数和fork()函数的使用方法相同;常用fork() 函数来创建新进程;
#include<stdio.h> #include<unistd.h> int main() { pid_t id = fork(); if(id < 0) perror("fork failed\n"); else if(id == 0) { printf("子进程\n"); return 0; } else { printf("父进程\n"); } return 0; }在父进程调用fork()函数之后,内核会进行如下操作来创建新进程:
分配新的内存块和内核数据结构给子进程;将父进程调用fork()函数之后的代码和数据拷贝给子进程;添加子进程到系统进程列表中;fork返回,开始调度调度器;注意:父子进程之间代码共享;父子进程不再写入时,数据也是共享的,当任意一方试图写入时,便会以写时拷贝的方式各自私有一份数据;
进程退出的三种场景:
代码运行结束,结果正确;代码运行结束,结果不正确;代码异常退出;进程异常退出的本质:进程收到了操作系统发来的信号;
进程退出的常见方法:
正常退出: 从main函数中退出; 调用exit()退出; 调用_exit()退出;这三种退出方法的异同:
一般从main函数中退出都是使用return 退出的,在main函数中使用return n退出等同于执行exit(n)退出,main的运行时函数会将main的返回值当做exit的参数;exit()函数退出的最后,也会调用_exit(),但调用exit()退出和调用_exit()退出的不同就是exit函数在调用_exit()会执行做一些工作(执行用户通过 atexit或on_exit定义的清理函数;关闭所有打开的流,所有的缓存数据均被写入);所以,直观上看来就是,调用exit()函数退出有可能会比调用_exit()函数退出多显示一些内容; //调用_exit()退出 #include<unistd.h> #include<stdio.h> int main() { printf("_exit()"); _exit(); } //调用exit()退出 #include<unistd.h> #include<stdio.h> int main() { printf("exit()"); _exit(); } 异常退出: 进程在运行时,按下Ctrl+c,进程被强制退出;