记录几个进程控制相关函数
目前已有fork、getpid、exec,持续更新~
fork
作用:可以理解为,复制父进程的资源,创建子进程。父子进程的数据、堆栈段相同,代码段共享。
(实际操作上,由于fork常与exec连用,导致之前的复制是无用功,所以采用写时复制技术COW)
这句话讲的是子进程的数据和代码运行情况,子进程会带着父进程直到fork处的所有变量的值,继续执行fork后的代码。
就像鸣人的影分身,被人砍了一刀之后发现一个人干不过对方,
于是使用fork影分身,分身被召唤时说“是兄弟就来砍我”,于是分身就带着被砍的一刀出现了,(父子进程的数据、堆栈段相同)
之后鸣人和分身一起搓丸子,(代码段共享,执行的代码相同)
分身在左,鸣人在右,(通过if(fork){……}将父子进程需要执行的代码进行区分)
搓完丸子后,分身被砍死,鸣人带着丸子干死敌人,鸣人胜利了。(实际上父子进程的运行顺序并不一定,结束顺序也不一定,通常子进程先运行先结束)
纯属扯淡,看看就行~~
一个有趣的例子+讲解https://www.cnblogs.com/bwangel23/p/4190043.html
返回值类型:pid_t,相当于int,
pid_t类型变量初始化时值为0。
返回值:fork调用一次,返回两次,返回值有三种。
fork在调用的两个进程中都会有返回值,即父进程调用fork一次,父子进程都有返回值,
而返回值可能的取值有三种,正数(父进程中的返回值,等于子进程的pid)、0(子进程中的返回值)、负数(error,没出现过这种情况)
可以将父子进程当成链表,旧结点使用fork在链尾增加结点,并返回新增节点的序号,由于新增节点没有继续fork,则会返回0。
总结,fork的神奇之处在于返回值和功能(好像函数也就这两点比较重要吧)
getpid
返回值:返回当前进程的pid,
这里的返回值需要和fork返回值进行区分,fork父进程返回的是被创建的子进程的pid,子进程返回0。
getppid
返回值:返回当前进程的父进程的pid,与getpid区分
exec函数族
作用:常用于fork的子进程。fork的子进程会执行与父进程相同的程序,这往往是没有意义的。而对子进程用exec就可以借着子函数的身份(PID、PCB)运行与父进程程序不同的其他可执行文件。
内容:exec函数传递的参数分为3部分,即可执行文件的路径、命令行中的参数、环境变量,
可执行文件的路径:操作系统运行一个可执行文件需要它的路径,我们可以输入可执行文件的绝对路径来运行,也可以将可执行文件的路径存储在环境变量path中,当操作系统要运行这个可执行文件时,先找找当前目录下有没有符合的文件名,没有就查找环境变量path,如果有就找到执行,没有就报错。
环境变量其实就是操作系统这个大的程序的许多全局变量,path仅是其中的一个,这些全局变量一起存储着操作系统运行某些程序时所需要的信息(比如路径、系统时间),而不用用户每次都手动输入,非常方便
命令行参数:在命令行中正常运行可执行文件后面跟的参数
环境变量:这里的环境变量是由用户在程序中自定义的,而非系统默认的环境变量,如果有自定义的环境变量,会自动按照自定义的来寻找可执行文件
区分:依据上述三类参数的传递形式的不同,将exec族函数可以分成6种:
这几个函数均统一以exec开头,
后加p的:代表path,有p的写可执行文件名(兼容绝对路径),没有p的写可执行文件的绝对路径
后加 l 的:代表list,有l的将命令行参数以字符串“……”的形式作为实参传递,没有l的一定有v
后加v的:代表vector,有v的将命令行参数存储在字符数组中,以字符数组的形式作为实参传递
后加e的:代表environment,有e的后面需要添加自定义的环境变量,以字符数组的形式作为实参传递
命令行参数无论以字符串还是字符数组作为实参,都需要保证以文件名开头,以NULL结尾
环境变量的字符数组也以NULL结尾
例如,以命令ls -la为例,分别用6个exec函数进行表示,
char *argv_exec[]={"ls", "-l", "-a", NULL};
char *envp[]={"PATH=/tmp", "USER=xiaoming", NULL};
execl("/bin/ls", "ls", "-l", "-a", NULL); //绝对路径,字符串形式的命令行参数, 无自定义环境变量
execlp("ls","ls","-l","-a",NULL); //文件名, 字符串形式的命令行参数, 无自定义环境变量
execle("/bin/ls","-l","-a", NULL, envp); //绝对路径,字符串形式的命令行参数, 字符数组形式的自定义环境变量
execv("/bin/ls", argv_exec); //绝对路径,字符数组形式的命令行参数,无自定义环境变量
execvp("ls",argv_exec); //文件名, 字符数组形式的命令行参数,无自定义环境变量
execve("/bin/ls",argv_exec, envp); //绝对路径,字符串形式的命令行参数, 字符数组形式的自定义环境变量
wait函数
作用:等待任意一个子进程终止。紧接在fork之后,在保证子进程运行在父进程之前。
返回值:运行成功,返回子进程的pid;失败,返回-1
注意与sleep区分