更多点子:linux—目录索引(知识小渠道)
两次fork 可以让两个进程同时运行,一次fork 只能一个运行一个阻塞 在子进程里再调一个进程,然后让儿子死亡,孙子成孤儿,之后父亲和孙子一起并发运行
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/wait.h> int main(void) { pid_t pid = fork(); if(pid==0)//子进程 { if(fork()>0)//子进程本身,说明孙子创建失败了 exit(0); for(;;) { printf("孙子\n"); sleep(1); } else { wait(NULL); for(;;) { printf("老子\n"); sleep(1); } } } }编写xshell WIFEXITED(status) // 如果正常退出,返回真 WEXITSTATUS(status) //如果正常退出,返回退出码 WIFSIGNALED(status) // 如果被信号打断,返回真 WTERMSIG(status) // 如果被信号打断,得到信号值
pid_t waited(pid_t pid,int *status,int options); //0 WNOHANG pid > 0 等待进程ID等于pid的子进程死亡 pid = 0 调用者进程所在进程组的任何一个子进程死亡 pid = -1 等待任何一个子进程死亡 pid < -1 |pid|进程组的任何一个子进程死亡
exec 替换进程空间,但这不是一个函数,是一批函数,下面的enecvp只是其中的一个 进程空间替换(磁盘到虚拟): 本来进程有虚拟的空间,现在到磁盘上到一段空间,来放进程的数据 PDB不替换 int execvp(const char *file,char *const argv[]) //用file(可执行程序名)替换这个进程,占用它的空间
#include<stdio.h> #include<unistd.h> #include<string.h> #include<stdlib.h> #include<sys/wait.h> #include<ctype.h> void do_enecvp(int argc,char* argv[]) { pid_t pid=fork(); if(pid==0)//子进程 { execvp(argv[0],argv);//替换子进程,执行它 perror("execvp");//如果命令不存在,会出错 exit(0);//能执行到这,就说明已经出错了,退出吧 } wait(NULL);//父进程等待子进程死亡,子进程是这的envp } void do_parse(char *buf) { char *argv[8]={}; int argc=0; int i; int status=0; for(i=0;buf[i]!=0;i++)//重置buf内各个的状态 { if(status==0&&!isspace(buf[i]))//非空白符 { argv[argc++]=buf+i; status=1; } else if(isspace(buf[i]))//空白符 { status=0; buf[i]=0;//拿这把字串隔开 } } argv[argc]=NULL; do_execvp(argc,argv);//让父进程等待,子进程运行,所以把它给传过去 } int main(void) { char bur[1024]={}; while(1) { printf("my shell> "); memset(buf,0x00,sizeof(buf)); while(scanf("%[~\n]%*c",buf)==0)//不接收\n,然后读取\n丢弃,如果一上来就是\n,那后面的就不读了,就会导致换行一直在输入缓存,就一直在循环 { //==0说明scanf没有成功,成功的话返回2 printf("my shell> "); while(getchar()!="\n");//走到这说明scanf没有成功,所以要把这一行给清空 } if(strncmp(buf,"exit",4)==0)//如果输入的是exit就结束掉当前进程 exit(0); do_parse(buf); } }如果有什么不对的地方,可以评论告诉我,望指导!
