自己做采集电影网站,wordpress 主题哪个好,广州公司建站模板,新公司董事长致辞做网站创建子进程
函数声明如下#xff1a;
pid_t fork(void);
返回值#xff1a;失败返回-1#xff0c;成功返回两次#xff0c;子进程获得0(系统分配)#xff0c;父进程获得子进程的pid
注意#xff1a;fork创建子进程#xff0c;实际上就是将父进程复制一遍作为子进程
pid_t fork(void);
返回值失败返回-1成功返回两次子进程获得0(系统分配)父进程获得子进程的pid
注意fork创建子进程实际上就是将父进程复制一遍作为子进程但子进程只执行fork之后的代码不执行fork之前的代码。这里的复制代表了父子进程的空间是独立的互不影响。
孤儿进程与僵尸进程
如果父进程先结束那么子进程变成孤儿进程最终被init进程收养并且子进程变为后台进程。
如果子进程先结束但父进程没有回收子进程那么子进程变成僵尸进程。
fork基本使用方法
pid fork();
if(pid0){perror(fork);return -1;
}else if(pid 0){//子进程代码
}else if(pid 0){//父进程代码
}
进程结束
函数声明如下
void exit(int status);void _exit(int status);
void _Exit(int status);
exit结束进程后会刷新缓冲区其余这三个函数没有区别。
status返回给系统的状态值
注意main函数结束会隐式调用exit函数所以在main函数结束时会刷新缓冲区。
exit刷新缓冲区实验 进程回收
函数声明如下
pid_t wait(int *wstatus);
pid_t waitpid(pid_t pid, int *wstatus, int options);
返回值成功返回回收的子进程的pid失败返回EOF
wstatus保存子进程结束的状态NULL代表直接释放子进程的PCB不接收返回值。
pid想要回收的子进程的pid-1代表任意子进程0代表进程组中的任意子进程
options回收的方式
0阻塞等待子进程结束WNOHANG不阻塞等待子进程结束子进程未结束也返回继续执行下面代码。
注意父进程调用该函数后一直处于阻塞状态直到子进程结束
通过宏来解析wstatus
wstatus中包含了是否正常退出、exit返回值、是否被信号结束、结束进程的信号类型。
解析的宏如下
宏含义WIFEXITED(wstatus)判断子进程是否正常退出WEXITSTATUS(wstatus)获取子进程返回值即exit的值WIFSIGNALED(wstatus)判断子进程是否被信号结束WTERMSIG(wstatus)获取结束子进程的信号类型
wait测试代码
具体代码实现如下
#include sys/types.h
#include unistd.h
#include sys/wait.h
#include stdlib.h
#include stdio.h
#include errno.h
int main(){pid_t pid;int wstatus;if((pid fork()) 0){return -1;}else if(pid 0){sleep(10);printf(now child exit\n);exit(2);}else{wait(wstatus);//以阻塞方式等待子进程退出printf(是否正常退出:%d\n,WIFEXITED(wstatus));printf(子进程的返回值为%d\n,WEXITSTATUS(wstatus));printf(子进程是否被信号结束%d\n,WIFSIGNALED(wstatus));printf(结束子进程的信号类型%d\n,WTERMSIG(wstatus));}return 0;
}
代码执行结果如下 waitpid填写WNOHANG实验
当子进程退出后子进程的pid会一直存在直到被回收。当写入WNOHANG时waitpid不会进入阻塞。但可以通过循环的模式一次次判断是否有子进程需要回收。
具体代码实现如下
#include sys/types.h
#include unistd.h
#include sys/wait.h
#include stdlib.h
#include stdio.h
#include errno.h
int main(){pid_t pid;int wstatus;if((pid fork()) 0){return -1;}else if(pid 0){sleep(5);printf(now child exit\n);exit(2);}else{while(1){if(waitpid(pid,wstatus,WNOHANG) 0){ //当子进程退出后,父进程退出whilebreak;}printf(father is running\n);sleep(1);}}return 0;
}
代码执行结果如下 进程执行其他程序
1、exec
exec函数的作用
进程调用exec函数执行某个程序调用后进程的当前内容被指定的程序替换但进程号不变。
利用exec可以实现父子进程执行不同的程序创建子进程-子进程调用exec执行其他功能。
函数声明如下
int execl(const char *pathname, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execv(const char *pathname, char *const argv[]);
int execvp(const char *file, char *const argv[]);
返回值失败返回-1
pathname执行程序的路径
file执行程序的名字会从环境变量PATH中寻找该执行程序
arg执行程序的参数第0个参数为程序名
argv执行程序的参数以字符串数组形式呈现
...写NULL、0、(char*)0这三个中的其中一个
示例使用execl实现 ls -li . 的功能
具体代码实现如下
#include unistd.h
#include stdio.hint main(){//ls -li . 有三个参数,ls是第0个参数execl(/bin/ls,ls,-li,.,NULL);printf(get\n);return 0;
}代码运行结果如下 示例使用execv实现 ls -li . 的功能
具体代码实现如下
#include unistd.h
#include stdio.h
#include errno.h
int main(){//这里最后一个NULL不需要加双引号char* a[] {ls,-li,.,NULL};if(execv(/bin/ls,a) -1){perror(execv);}printf(get\n);return 0;
}代码运行与execl一样
2、system
system的作用
执行一个指令调用system后会等待指令执行结束之后继续执行下面的代码而不是像exec那样下面的代码被替代。
函数声明如下
int system(const char *command);
返回值失败返回EOF
command一个指令以字符串形式呈现
示例使用system实现 ls -li . 的功能
具体代码实现如下
#include stdlib.h
#include stdio.h
#include errno.h
int main(){system(ls -li .);printf(get\n);return 0;
}代码运行结果如下