【Linux】进程控制!!!

xiaoxiao2021-02-28  61

在linux里面常用的调度算法是时间片轮转法,即每一个进程分为很多的块,每一块都只能占用CPU固定的时间,当时间到,这个进程就必须放弃对CPU的使用权限。然后CPU去执行下一个进程。 在使用fork()函数创建一个子进程的时候,父进程和子进程执行的先后顺序是不确定的,所以子进程和父进程执行行为先后次序是不确定的。但是在除开使用fork()函数的同时也可以使用vfork()来创建进程,vfork()在创建进程的时候,必须是在子进程执行完之后再去执行父进程。在fork()创建进程的时候采用的是写实拷贝技术,但是使用vfork()函数的时候即使写时也不拷贝,即在改变子进程的同时也改变了父进程的数据。也因此,在使用vfork()创建进程的时候会出现一些意想不到的事情。

进程等待: 必要性:在使用多进程的时候,父进程需要知道子进程的退出信息,同时也需要回收子进程的资源,以及子进程的死亡信息。

进程等待的方法: pid_t wait(int * status); 如果wait函数正常返回,则返回死亡子进程的ID,其中status里面保存的是子进程退出的基本信息。如果wait函数调用失败则返回-1。

例如:

#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<string.h> #include<sys/wait.h> int main() { pid_t pid; printf("begin fork()!\n"); pid = fork(); if(pid == -1) perror("fork():"); if(pid == 0) { printf("I'm child!\n"); sleep(5); } else { int status; wait(&status); printf("wait end!\n"); } return 0; }

在输出I'm child!之后睡眠5秒之后再输出wait end!

在这个程序里面,当使用fork()函数之后,父进程和子进程同时存在,但是在父进程里面使用了wait函数,这时候在子进程没有退出之前,父进程一直在wait函数地方等待,直到子进程在执行完之后再退出,这时候wait函数返回,父进程开始执行下面的代码。

pid_t waitpid(pid_t pid,int* status,int pation);

pid: - pid = -1 表示任意一个子进程退出,则返回 - pid >0 表示等待和pid相同的ID进程退出则返回。 status:

WIFEXITED : 判断自己成是否是正常退出WEXITSTATUS:如果返回statu>0,则提取子进程的退出码

pation: - WNOHANG:如果指定子进程没有返回,则返回0,如果正常返回则返回指定子进程的ID。在程序执行的过程中不等待。 例如:

int main() { pid_t r; pid_t pid; int status; pid = fork(); if(pid == -1) perror("fork():"); else if(pid == 0) { printf("hehe\n"); } else { r = wait(&status); printf("%d\n",WEXITSTATUS(status)); } }

waitpid函数是在指定子进程退出之后waitpid函数在返回,使用waitpid函数就可以实现指定进程死亡之后,在执行父进程。

在子进程没有执行结束,调用wait/waitpid函数会处于阻塞状态。若子进程正常返回,则wait/waitpid函数正常返回,若不存在子进程或者指定子进程,则wait/waitpid函数立即报错。

若果子进程存在并且子进程退出,则wait函数正常返回,回收子进程的资源,获得子进程的退出信息。 若子进程处于运行状态,则wait函数处于阻塞状态,等待子进程退出。 若子进程不存在,wait函数立即报错。

利用进程等待实现myshell:

#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/wait.h> #include<ctype.h> #include<string.h> void do_action (char* argv[]) { if(fork() == 0) execvp(argv[0],argv); else wait(NULL); } void do_pose(char *buf) //将输入的字符串拆分 { int i=0; int status = 0; char * argv[8]; int argc = 0; for(;buf[i] != '\0';i++) { if(status == 0 && !isspace(buf[i])) { argv[argc++] = buf + i; status = 1; } else if(isspace(buf[i])) { buf[i] = 0; status = 0; } } argv[argc] = NULL; do_action(argv); } int main() { char buf[1024]; while(1) { printf(">:"); scanf("%[^\n]%*c",buf); if(strcmp(buf,"exit")==0) exit(0); do_pose(buf); } }
转载请注明原文地址: https://www.6miu.com/read-2049970.html

最新回复(0)