进程间控制

进程间控制

一、创建进程:fork()函数

#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
  • 功能:
    用于从一个已存在的进程中创建一个新进程,新进程称为子进程,原进程称为父进程。
  • 参数:
  • 返回值:
    成功:子进程中返回 0,父进程中返回子进程 ID
    失败:返回-1,perror打印原因。

父子进程关系

父子进程几乎所有的资源属性都是一样的,都有各自的堆栈区,变量的虚拟地址也是一样的,文件描述符也是一样的,只有进程号,计时器等少量信息是不同的,因此fork()函数的代价很大。

二、等待子进程退出函数:wait()函数

#include <sys/wait.h>
pid_t wait(int *statloc);
  • 功能:

    在进程结束时, 内核释放该进程所有的资源、包括打开的文件、占用的内存等。但是仍然为其保留一定的信息,这些信息主要主要指进程控制块PCB的信息(包括进程号、退出状态、运行时间等)。 wait()函数的作用是回收子进程剩下的资源。有三种情况:

    1. 所有子进程都在运行,则阻塞。
    2. 有一个子进程已终止,等待父进程获取其终止状态,则取得改子进程的终止状态并返回。
    3. 没有任何子进程,则出错返回。
  • 参数:int *statloc

    ​ 状态码存在statloc所指内存处。

  • 返回值:成功返回进程id,出错返回0或-1。

#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *statloc, int options);

waitpid()wait()的区别:

  • wait()函数在子进程没终止的时候会阻塞,waitpid()可以设置选项不阻塞
  • waitpid()可以设置等待的进程id

pid_t pid

  • pid == -1:等待任意一个子进程
  • pid > 0 :等待pid
  • pid == 0:等待调用进程组id的任意子进程
  • pid < -1:等待组id等于pid绝对值的任意子进程

options

  • WNOHANG:若pid指定的子进程不是立即可用的,则waitpid()不阻塞,返回0;

返回值:
1. 当正常返回的时候,waitpid() 返回收集到的已经回收子进程的进程号;
2. 如果设置了选项 WNOHANG,而调用中 waitpid() 发现没有已退出的子进程可等待,则返回 0;
3. 如果调用中出错,则返回-1,这时 errno 会被设置成相应的值以指示错误所在,如:当 pid 所对应的子进程不存在,或此进程存在,但不是调用进程的子进程,waitpid() 就会出错返回,这时 errno 被设置为 ECHILD;

三、exec函数

exec函数不创建新进程,只用磁盘上的程序替换当前进程的正文段、数据段、堆段和栈段。然后从main函数开始运行。

exec函数族使用说明

#include <unistd.h>
int execl(const char *pathname, const char *arg, ...)
int execle(const char *pathname, const char *arg, ..., char *const envp[])
int execv(const char *pathname, char *const argv[])
int execve(const char *pathname, char *const argv[], char *const envp[])
    
int execlp(const char *filename, const char *arg, ...)
int execvp(const char *filename, char *const argv[])

l 代表 list

命令的参数是列举出来的execl("/bin/ls","ls","./",NULL),第一个参数是路径,后面的参数组合起来就是命令行要输入的命令

v代表vector

命令的参数是用字符串数组的形式给出

char *const ps_argv[] ={"ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL};
execv("/bin/ps", ps_argv);

e 代表 environment

传递新的环境变量

char *const ps_envp[] ={"PATH=/bin:/usr/bin", "TERM=console", NULL};
execle("/bin/ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL, ps_envp);

p代表PATH

$PATH环境变量里搜索程序名

char *const ps_argv[] ={"ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL};
execvp("ps", ps_argv);
posted @ 2022-01-18 14:11  hellozhangjz  阅读(45)  评论(0编辑  收藏  举报