进程创建
#include <unistd.h>
pid_t fork(void);
//失败返回-1;
//成功时:父进程返回子进程的进程号,子进程返回0
eg.
pid_t pid
if((pid = fork() < 0){
perror("fork");
return -1;
}else if(pid == 0){
printf("child process:my pid is %d\n",getpid());
}else{
printf("parent process:my pid is %d\n",getpid());
}
父子进程
- 子进程继承了父进程的内容,几乎复制了所有内容,包括数据、系统数据、代码、指令、父进程打开的文件。。。
- 父子进程有独立的地址空间,互不影响
- 若父进程先结束
子进程称为孤儿进程,被init进程收养(系统规定,每个进程结束时由父进程回收,如果是孤儿进程则由init进程收养)
子进程变为后台进程 - 若子进程先结束
父进程如果没有及时回收,子进程变成僵尸进程
进程-思考
- 子进程从何时开始运行?
子进程复制了父进程几乎所有内容,包括PC值。父进程执行了fork,所以子进程是在fork的下一条语句开始运行。 - 父子进程谁先执行?
linux没有规定,不确定,通常情况下父进程执行完fork之后,父进程时间片还没有执行完,所以父进程会接着执行。如果是执行完了,则先执行子进程。 - 父进程能否多次调用fork?子进程呢?
理论上没有限制
进程结束
#include <stdlib.h>
void exit(int status);
#include <unistd.h>
void _exit(int status);
//区别:exit结束进程时会刷新(流)缓冲区
exec函数族
- 进程调用exec函数族执行某个程序
- 进程当前内容被指定的程序替换
- 实现让父子进程执行不同的程序
父进程创建子进程
子进程调用exec函数族
父进程不受影响
execl/execlp
#include <unistd.h>
int execl(const char *path,const char *arg,...);//成功时执行指定的程序,无返回值;失败时返回EOF
//path 执行的程序名称,包含路径
//arg... 传递给执行的程序的参数列表
int execlp(const char *file,const char *arg,...);
//file 执行的程序的名称,在PATH中查找
eg.
//执行ls命令,显示/etc目录下所有文件的详细信息
if(execl("/bin/ls","ls","-a","-l","/etc",NULL) < 0){
perror("execl");
}
execv/execvp
#include <unistd.h>
int execv(const char* path,char *const argv[]);
int execvp(const cha *file,char *const argv[]);
eg.
char *arg[] = {"ls","-a","-l","/etc",NULL};
if(execv("/bin/ls",arg) < 0 ){
perror("execv");
}
if(execvp("ls",arg) < 0){
perror("execvp");
}
system
#include <stdlib.h>
int system(const char *command);
//成功时返回命令command的返回值,失败时返回EOF
//当前进程等待command执行结束后才继续执行
L5-D1