进程间控制
进程间控制
一、创建进程: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()
函数的作用是回收子进程剩下的资源。有三种情况:- 所有子进程都在运行,则阻塞。
- 有一个子进程已终止,等待父进程获取其终止状态,则取得改子进程的终止状态并返回。
- 没有任何子进程,则出错返回。
-
参数:
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
:等待pidpid == 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);