进程相关函数使用

211 阅读3分钟

4月「掘金·日新计划」第5天

一、相关函数

1.1 getpid getppid

  1. 当前进程id
  2. 父进程id

1.2 fork

功能:

  1. 创建子进程
  2. fork后面代码,会执行2次,父子进程各一次

返回值:返回2次

  1. 返回值0,子进程
  2. 返回非负数,父进程,返回子进程pid
  3. 返回-1,调用失败

1.2.1 c程序存储空间分配情况

  1. 旧Linux,全拷贝,数据拷贝
  2. 新Linux,写时拷贝,只有对数据写的时候才会拷贝
  3. 代码正文共享

1.3 vfork

  1. 与fork区别

    1. vfork直接使用父进程存储空间,不拷贝
    2. vfork保证子进程先运行,子进程调用exit退出后,父进程吃执行

1.4 exit,exit,Exit

exit,_exit,_Exit
  1. exit是对另外2种的封装 先保存缓冲区数据
  2. exit是c库函数 另外2是系统调用,直接退出
  3. 异常退出,调用abort

1.5 wait,waitpid

pid_t wait(int *status)

功能:等待子进程退出

  1. 父进程阻塞

  2. 等待子进程退出,子进程使用exit(退出码int类型)退出

  3. wait接收退出码,需要使用宏解析,才能得到正确退出码

    1. WIFEXITED,正常终止,为真

      正常终止使用WEXITSTATUS(status)获取退出码

    2. WIFSIGNALED,异常退出,为真,abort函数退出

  4. WIFSTOPPED,若为暂停当前子进程返回状态,为真

  5. WIFCONTINUED,

pid_t waitpid(pid_t pid,int *status,int options)

参数:

  1. pid

    1. pid==-1,等待任意子进程,waitpid和wait等效
    2. pid>0,等待与pid相等的子进程
    3. pid==0,等待其组ID等于调用进程组ID的任一子进程
    4. pid<-1,等待其组ID等于pid绝对值的任一子进程
  2. 和wait一样

  3. 常量宏

    1. WNOHANG,waitpid不阻塞

注意点:

  1. wait会让父进程阻塞 waitpid会让子进程成为僵尸进程 上面前提条件和fork用
  2. vfork和wait,waitpid用可以改变父进程变量值 fork不能改变。会让父进程阻塞

1.5.1 僵尸进程

  1. 父进程等待子进程退出,并收集退出状态
  2. 不收集子进程,子进程变成僵尸进程(z+就是僵尸进程,ps指令查看)

1.5.2 孤儿进程

  1. 子进程还没结束,父进程就结束了
  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[]);

功能:

  1. 调用可执行文件执行

各后缀含义:

  1. l:参数写函数里

    execl("/bin/ls","ls", "-l", NULL)
    
  2. p:在环境变量PATH,里找

  3. v:参数,用指针数组

    char * const arg[] = {"ls", "-l", NULL};
    execve("/bin/ls", arg, NULL);
    
  4. e:使用新的环境变量

参数:

  1. path:可执行文件路径名

  2. arg:可执行程序带的参数,第一个参数为可执行文件名,以NULL结束

  3. file:如果参数file中包含/,则就将其视为路径名,否则就按 PATH环境变量,在它所指定的各目录中搜寻可执行文件。

    1. 查看环境变量,修改环境变量

      echo $PATH
      export PATH=$PATH:加的路径
      

返回值:

  1. 成功不返回 失败-1,并设置errno,然后从原程序接着执行

注意:exec族函数,会完全替换为另一个程序,程序本身后面的内容就不执行了

1.7 system

include <stdlib.h>
int system(const char *command);
sh -c ./程序名

返回值:

  1. 成功返回进程状态值
  2. sh不能执行,返回127
  3. 失败返回-1

system是封装后的fork加exec 与exec区别:system执行后会返回断点,继续执行 注:会使进程阻塞,直到system的程序执行完

1.8 popen

FILE *popen(const char *command, const char *cype);
int pclose(FILE *stream);

参数:

  1. 可执行文件 ls
  2. r,w

返回值:FILE*

  1. 可以获取输出结果,用fread读取结果,可以直接printf输出,也可以写入文件中。屏幕上不会直接打印出来
  2. 用法和fopen差不多
  3. 例:fp=popen(“ps”,“r”)