4月「掘金·日新计划」第5天
一、相关函数
1.1 getpid getppid
- 当前进程id
- 父进程id
1.2 fork
功能:
- 创建子进程
- fork后面代码,会执行2次,父子进程各一次
返回值:返回2次
- 返回值0,子进程
- 返回非负数,父进程,返回子进程pid
- 返回-1,调用失败
1.2.1 c程序存储空间分配情况
- 旧Linux,全拷贝,数据拷贝
- 新Linux,写时拷贝,只有对数据写的时候才会拷贝
- 代码正文共享
1.3 vfork
-
与fork区别
- vfork直接使用父进程存储空间,不拷贝
- vfork保证子进程先运行,子进程调用exit退出后,父进程吃执行
1.4 exit,exit,Exit
exit,_exit,_Exit
- exit是对另外2种的封装 先保存缓冲区数据
- exit是c库函数 另外2是系统调用,直接退出
- 异常退出,调用abort
1.5 wait,waitpid
pid_t wait(int *status)
功能:等待子进程退出
-
父进程阻塞
-
等待子进程退出,子进程使用exit(退出码int类型)退出
-
wait接收退出码,需要使用宏解析,才能得到正确退出码
-
WIFEXITED,正常终止,为真
正常终止使用WEXITSTATUS(status)获取退出码
-
WIFSIGNALED,异常退出,为真,abort函数退出
-
-
WIFSTOPPED,若为暂停当前子进程返回状态,为真
-
WIFCONTINUED,
pid_t waitpid(pid_t pid,int *status,int options)
参数:
-
pid
- pid==-1,等待任意子进程,waitpid和wait等效
- pid>0,等待与pid相等的子进程
- pid==0,等待其组ID等于调用进程组ID的任一子进程
- pid<-1,等待其组ID等于pid绝对值的任一子进程
-
和wait一样
-
常量宏
- WNOHANG,waitpid不阻塞
注意点:
- wait会让父进程阻塞 waitpid会让子进程成为僵尸进程 上面前提条件和fork用
- vfork和wait,waitpid用可以改变父进程变量值 fork不能改变。会让父进程阻塞
1.5.1 僵尸进程
- 父进程等待子进程退出,并收集退出状态
- 不收集子进程,子进程变成僵尸进程(z+就是僵尸进程,ps指令查看)
1.5.2 孤儿进程
- 子进程还没结束,父进程就结束了
- Linux为防止过多孤儿进程,init进程会成为孤儿进程新的父进程
1.6 exec族函数
#include <unistd.h>
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,..., 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[]);
功能:
- 调用可执行文件执行
各后缀含义:
-
l:参数写函数里
execl("/bin/ls","ls", "-l", NULL) -
p:在环境变量PATH,里找
-
v:参数,用指针数组
char * const arg[] = {"ls", "-l", NULL}; execve("/bin/ls", arg, NULL); -
e:使用新的环境变量
参数:
-
path:可执行文件路径名
-
arg:可执行程序带的参数,第一个参数为可执行文件名,以NULL结束
-
file:如果参数file中包含/,则就将其视为路径名,否则就按 PATH环境变量,在它所指定的各目录中搜寻可执行文件。
-
查看环境变量,修改环境变量
echo $PATH export PATH=$PATH:加的路径
-
返回值:
- 成功不返回 失败-1,并设置errno,然后从原程序接着执行
注意:exec族函数,会完全替换为另一个程序,程序本身后面的内容就不执行了
1.7 system
include <stdlib.h>
int system(const char *command);
sh -c ./程序名
返回值:
- 成功返回进程状态值
- sh不能执行,返回127
- 失败返回-1
system是封装后的fork加exec 与exec区别:system执行后会返回断点,继续执行 注:会使进程阻塞,直到system的程序执行完
1.8 popen
FILE *popen(const char *command, const char *cype);
int pclose(FILE *stream);
参数:
- 可执行文件 ls
- r,w
返回值:FILE*
- 可以获取输出结果,用fread读取结果,可以直接printf输出,也可以写入文件中。屏幕上不会直接打印出来
- 用法和fopen差不多
- 例:fp=popen(“ps”,“r”)