服务热线
15527777548/18696195380
发布时间:2022-01-05
简要描述:
前言在《关于进程创建分析》一文中,对一些linux命令以及进程创建、进程状态做了讲解,还做了几个小lab。在本篇文章中,将继续延续上篇文章的知识,讲解一些文件操作指令并做一些小...
在《关于进程创建分析》一文中,对一些linux命令以及进程创建、进程状态做了讲解,还做了几个小lab。在本篇文章中,将继续延续上篇文章的知识,讲解一些文件操作指令并做一些小lab。
如果这里是:wait(NULL),代表父进程只回收资源,不关心子进程退出状态。
#include unistd.h>#include stdlib.h>#include sys/wait.h>int main(int argc,char *argv[]){pid_t x;x = fork();if(x>0){sleep(3);printf("3s:I was father ,i will wait my child\n");wait(NULL);printf("I have wait my child\n");}if(x==0){sleep(8);printf("I will death in 8s\n");}}
这种情况会出现僵尸进程问题。
#include stdio.h>#include unistd.h>#include stdlib.h>#include sys/wait.h>int main(int argc,char *argv[]){pid_t x;x = fork();if(x>0){sleep(8);printf("8s:I was father ,i will wait my child\n");wait(NULL);printf("I have wait my child\n");}if(x==0){sleep(3);printf("I will death in 3s\n");}}

可以看到这里是有僵尸程序的。
子进程等到父进程退出为止,在寻求一个新的父亲作为父进程,帮自己回收资源。
#include stdio.h>#include unistd.h>#include stdlib.h>#include sys/wait.h>int main(int argc,char *argv[]){pid_t x;x = fork();if(x>0){sleep(8);printf("8s:I was father ,i will wait my child\n");printf("I have wait my child\n");}if(x==0){sleep(3);printf("I will death in 3s\n");}}
子进程在退出时,需要调用一个函数,就可以把退出状态返回给父进程。
exit()_Exit()_exit()
这三个函数都可以使得进程退出,并且可以将退出状态返回给父进程。
exit()先清洗缓冲区,再退出。
导致普通进程结束:
#includestdlib.h>void exit(int status)
参数:
例题:父进程去回收子进程的资源,子进程正常退出,输出 ok,异常退出,输出err
#include stdio.h>#include stdlib.h>#include unistd.h>#include sys/wait.h>int main(int argc,char *argv[]){pid_t x;x = fork();if(x>0){sleep(1);wait(if(state==0){printf("ok");}else{printf("err");}}if(x==0)
![]()
{sleep(6);exit(0);}}
![]()
程序中,调用exit()函数与执行return语句有什么区别?
#include stdio.h>#include unistd.h>#include stdlib.h>#include sys/wait.h>int main (int argc ,char *argv[]){int n;printf("process mount :\n");scanf("%d",int i;pid_t x;//chanshengfor(i=0;in;i++){x = fork();if(x>0){continue;}if(x==0){break;}}if(x>0){for(i=0;in;i++){wait(NULL);}printf("parent pid=%d\n",getpid());}if(x==0){printf("child pid = %d\n",getpid());exit(0);}}

execute a file#include unistd.h>extern char **environ;int execl(const char *pathname, const char *arg, .../* (char *) NULL */);int execlp(const char *file, const char *arg, .../* (char *) NULL */);int execle(const char *pathname, const char *arg, .../*, (char *) NULL, char *const envp[] */);int execv(const char *pathname, char *const argv[]);int execvp(const char *file, char *const argv[]);int execvpe(const char *file, char *const argv[],char *const envp[]);
path:需要执行的那个程序的绝对路径
arg:以“,”分开所有参数,以NULL,作为结束标志(直接作为形参)
file:程序的文件名
argv:以”,“分开所有参数,以NULL作为结束标志(先放到一个数组中,再把数组作为形参)
envp:环境变量的路径
例题:让子函数实现ls -l操作
#include stdio.h>#include unistd.h>#include stdlib.h>#include sys/wait.h>int main(int argc,char *argv[]){pid_t x;x= fork();if(x>0){sleep(2);wait(NULL);exit(0);}if(x==0){execl("/bin/ls","ls","-l",NULL);}return 0;}
结论:只要执行了exec函数族,那么进程后面的代码会被覆盖。

可以看到并没有printf出。
vfork()NAMEvfork - create a child process and block parentSYNOPSIS#include sys/types.h>#include unistd.h>pid_t vfork(void);
fork是随机运行,vfork是父进程阻塞。
当子进程中调用exit()函数后者是exec函数族中的接口时,就会开始运行父进程的代码。
#include stdio.h>#include unistd.h>#include stdlib.h>#include sys/wait.h>int main(int argc,char *argv[]){pid_t x;x = vfork();if(x>0){printf("my child\n");}if(x==0){sleep(3);printf("child\n");execl("/bin/ls","ls","-l",NULL);}}



进程之间的资源是分开的,进程之间的资源没有办法进行交换。
NAMEpipe, pipe2 - create pipeSYNOPSIS#include unistd.h>
返回值:
成功0
失败-1
初始化成功
结果:
fd[0]-->读端
fd[1]-->写端
初始化的读端与写端文件描述符等于多少?
pipefd:一个具有2个int类型变量的数组。
例题:初始化的读端与写端的文件描述符
#include stdio.h>#include unistd.h>#include stdlib.h>#include sys/wait.h>int main(int argc,char *argv[]){int fd[2]={0};printf("fd[0]=%d\n",fd[0]);printf("fd[1]=%d\n",fd[1]);pipe(fd);printf("fd[0]=%d\n",fd[0]);printf("fd[1]=%d\n",fd[1]);return 0;}

进程这部分内容,是有很多值得研究的东西,还有资源共享、互斥、同步、锁等有关问题,使得用户使用更加方便。
如果您有任何问题,请跟我们联系!
联系我们
