精华内容
下载资源
问答
  • # p.join(3) #父进程必须等到子进程完成后才能继续执行 可设置等待超时时间 # print("我是主进程!!!")   # def task(i): # print("%s start" % i) # # time.sleep(2) # # print("%s stop" % i) # # if __name__...

    from multiprocessing import Process
    import time

    # def task(name):
    # print("%s start" % name)
    # time.sleep(3)
    #
    # print("%s stop" % name)
    #
    # if __name__ == '__main__':
    # p = Process(target=task,args=("jerry",))
    # p.start()
    # p.join(3) #父进程必须等到子进程完成后才能继续执行 可设置等待超时时间
    # print("我是主进程!!!")

     


    # def task(i):
    # print("%s start" % i)
    # # time.sleep(2)
    # # print("%s stop" % i)
    #
    # if __name__ == '__main__':
    # for i in range(1,11):
    # p = Process(target=task,args=(i,))
    # p.start()
    # print("主进程!!!!")

    # 我们的代码只负责 通知操作系统创建进程 创建完就继续其他代码
    # 但是操作系统什么时候创建完成 什么时候执行我们无法预知无法控制
    def task(i):
    print("%s start" % i)
    time.sleep(2)
    print("%s stop" % i)

    if __name__ == '__main__':
    start_time = time.time()
    ps = []
    for i in range(1,3):
    p = Process(target=task,args=(i,))
    p.start()
    ps.append(p)
    # 主进程等子进程结束
    for p in ps:
    p.join()

    print("主进程!!!!",time.time()-start_time)

    转载于:https://www.cnblogs.com/frank007/p/9925126.html

    展开全文
  • 父进程等待子进程结束 waitpid wait

    万次阅读 2015-11-09 17:02:08
    当一个进程由于某种原因停止时,内核并不是直接将为它保存的状态信息从内核移除,相反,进程会一直被保持在一种已经终止的状态,直到被它的父进程回收,当父进程回收已经终止的子进程时,内核会将子进程的

    我们一直在强调一个概念就是进程是一个程序执行的实例,是内核在虚拟概念下创建的实体,它实例化的体现在用户态就是程序代码和代码使用的变量(存储空间),在内核态就是内核为我们每个进程所保存的数据结构(状态信息)等。
    当一个进程由于某种原因停止时,内核并不是直接将为它保存的状态信息从内核移除,相反,进程会一直被保持在一种已经终止的状态,直到被它的父进程回收,当父进程回收已经终止的子进程时,内核会将子进程的退出状态传递给父进程,然后抛弃已经终止的进程,从此刻开始,这个进程才会消失,一个子进程结束但是还没有被父进程回收的进程叫做”僵尸进程”,要是父进程先于子进程结束,那么它的子进程就会称为”孤儿进程”,最终会被PID为1的init进程收养。什么?init进程?好眼熟,对,它是我们引入进程的概念时候提过的。下面我们将介绍父进程等待子进程结束的两个函数,wait()和waitpid()函数。
    首先我们来看下man wait的内容:

    #include <sys/types.h>
    #include <sys/wait.h>
    pid_t wait(int *status);  //status表示退出状态,指向子进程的退出码
    返回:如果成功,返回子进程的ID;如果失败,返回-1。
    pid_t waitpid(pid_t pid, int *status, int options);  //option可选择设置waitpid不堵塞
    返回:如果成功,返回子进程的ID;如果option设置为WNOHANG,则为0;如果其他错误,则为-1

    waitpid()函数:

    默认的,当option参数为0的时候,它挂起等待一个子进程的结束;如果子进程中一个进程在刚调用的时候就已经结束了,那么waitpid()就会立即返回,如果正常情况下,这两种都会返回已经终止的进程的PID,并且将这个进程从系统中去除。下面我们再来详细介绍下它的三个参数:

    (1):pid:判定等待集合的成员
    pid > 0 : 表示等待集合中进程号为pid的特定子进程。
    pid = -1 : 表示等待进程的任意一个子进程。
    pid = 0 : 表示等待其组ID等于调用进程的组ID的任意一个进程。

    (2):status:检查已回收的子进程的退出状态,主要是利用wait.h头文件中的几个宏来检测。
    WIFEXITED(status) : 如果子进程通过调用exit或者return正常终止,那么就返回真。
    WEXITSTATUS(status) : 返回一个正常终止的子进程的退出状态,返回子进程中exit或_exit的低八位。
    WIFSIGNALED(status) : 若子进程异常终止,它就取得一个非零值,表示真。

    (3):options : 修改默认行为,介绍最常用的一个。
    WNOHANG : 如果等待集合中的任意一个子进程都还没有终止,那么就立即返回,(返回值为0),默认的行为是挂起调用进程等待,直到有子进程结束,这样可以避免阻塞,我们还可以在等待子进程结束的同时干点别的什么事。
    下面我们来看一段代码:

    #include<stdio.h>
    #include<sys/types.h>
    #include<sys/wait.h>
    #include<errno.h>
    #include<unistd.h>
    #include<stdlib.h>
    
    int main(int argc,char *argv[])
    {
        pid_t pid;
        int status;
    
        printf("Hello\n");
        pid = fork();
        if(pid != 0) {
            if(waitpid(-1,&status,0) > 0) {
                if(WIFEXITED(status) != 0) {
                    printf("%d\n",WEXITSTATUS(status));
                }
            }
        }
        printf("Bye\n");
        exit(100);
    }

    这里写图片描述
    输出为什么是4行大家懂不懂呢,首先输出Hello没有什么解释的,然后在fork之后我们可以看做有两份一样的代码分别属于父进程和子进程,然后子进程输出Bye,此时的父进程已经被挂起等待子进程的结束,然后子进程100退出码退出,此时父进程结束挂起状态,WEXITSTATUS(status)输出退出码,接着向下执行,再次输出Bye!

    错误条件:如果调用进程没有子进程,那么waitpid()函数返回-1,并且设置errno的值为ECHILD;如果waitpid()函数被一个信号中断,那么返回-1,并且设置errno的值为EINTR。举个例子:

    #include<stdio.h>
    #include<sys/types.h>
    #include<sys/wait.h>
    #include<errno.h>
    
    int main(int argc,char *argv[])
    {
        pid_t pid;
        int status;
        pid = waitpid(-1,&status,0);
    
        printf("pid is %d\n",pid);
        if(errno == ECHILD) {
            perror("waitpid");
        }
    }

    这里写图片描述
    我们可以看到对于没有子进程的进程如果调用waitpid()函数的话返回-1,并且将errno值设置为ECHILD,我们可以用perror()函数打印出来错误原因是没有子进程。

    wait()函数

    介绍完waitpid()函数,wait()函数实际上就不用多说了,它是waitpid()函数的简单版本

    wait(status) = waitpid(-1,&status,0)。来段代码练练手:

    #include<stdio.h>
    #include<sys/wait.h>
    #include<sys/types.h>
    #include<unistd.h>
    #include<stdlib.h>
    
    int main(int argc,char *argv[])
    {
        int     pid;
        char    *msg;
        int     k;
        int     exit_code;
    
        pid = fork();
        switch(pid){
            case 0:{
                printf("curpid = %d,parentpid = %d\n",pid,getppid());
                msg = "children process is running";
                k = 5;
                exit_code = 55;
                break;
            }
            case -1:{
                perror("process creat failed\n");
                exit(-1);
            }
            default:{
                printf("childpid is %d ,parentpid is %d\n",pid,getpid());
                exit_code = 0;
                break;
            }
        }
        printf("------------------------%d\n",pid);
        if(pid != 0)
        {
            int   stat_val;                         // 值为0
            int   child_pid;
    
            child_pid = wait(&stat_val);     //wait函数的返回值是终止运行的子进程的pid, 遇到wait函数之后开始执行子进程.
            printf("child process has exited,pid = %d\n",child_pid);
            if(WIFEXITED(stat_val)){
                printf("child exited with code %d\n",WEXITSTATUS(stat_val));
            }
            else {
                printf("child exited abnormally\n");
            }
        }
        //让子进程暂停5秒
        else 
        {
            while(k-- > 0)
            {
                puts(msg);
                sleep(1);
            }
        }
        exit(exit_code);
    }
    

    这里写图片描述
    我们首先fork一个子进程,然后子进程执行的是case 0 中的代码以及下面else中的代码,父进程执行default中代码和下面if中的代码,但是父进程到wait函数的时候就会挂起来等待子进程的结束。子进程连续输出5次msg的内容之后退出,exit_code=55;这个会被父进程中的 WEXITSTATUS(stat_val) 检测到。

    展开全文
  • Linux父进程等待子进程结束

    千次阅读 2013-11-19 20:57:20
    进程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出。如果让它找到了这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一...
    wait()的函数原型是:
    #include <sys/types.h>  
    #include <sys/wait.h> 
    pid_t wait(int *status)


    进程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出。如果让它找到了这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。


    参数status用来保存被收集进程退出时的一些状态,它是一个指向int类型的指针。但如果我们对这个子进程是如何死掉的毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我们都会这样想),我们就可以设定这个参数为NULL,就象下面这样:
    pid = wait(NULL); 


    如果成功,wait会返回被收集的子进程的进程ID,如果调用进程没有子进程,调用就会失败,此时wait返回-1,同时errno被置为ECHILD。


    WIFEXITED(status) 这个宏用来指出子进程是否为正常退出的,如果是,它会返回一个非零值。


    WEXITSTATUS(status) 当WIFEXITED返回非零值时,我们可以用这个宏来提取子进程的返回值,如果子进程调用exit(5)退出,WEXITSTATUS(status)就会返回5;如果子进程调用exit(7),WEXITSTATUS(status)就会返回7。请注意,如果进程不是正常退出的,也就是说,WIFEXITED返回0,这个值就毫无意义。


    #include <stdlib.h>
    #include <stdio.h>
    #include <signal.h>
    #include <unistd.h>
    #include <sys/wait.h>
    void f(){
    printf("THIS MESSAGE WAS SENT BY PARENT PROCESS..\n");
    }


    main(){
    int i,childid,status=1,c=1;
    signal(SIGUSR1,f); //setup the signal value
    i=fork(); //better if it was: while((i=fork)==-1);
    if (i){
    printf("Parent: This is the PARENT ID == %d\n",getpid());
    sleep(3);
    printf("Parent: Sending signal..\n");
    kill(i,SIGUSR1); //send the signal


    //status is the return code of the child process
    wait(&status);
    printf("Parent is over..status == %d\n",status);


    //WIFEXITED return non-zero if child exited normally 
    printf("Parent: WIFEXITED(status) == %d\n",WIFEXITED(status));


    //WEXITSTATUS get the return code
    printf("Parent: The return code WEXITSTATUS(status) == %d\n",WEXITSTATUS(status));
    } else {
    printf("Child: This is the CHILD ID == %d\n",getpid());
    while(c<5){
    sleep(1);
    printf("CHLID TIMER: %d\n",c);
    c++;
    }
    printf("Child is over..\n");
    exit(2);
    }
    }


    输出:
    Child: This is the CHILD ID == 8158
    Parent: This is the PARENT ID == 8157
    CHLID TIMER: 1
    CHLID TIMER: 2
    Parent: Sending signal..
    THIS MESSAGE WAS SENT BY PARENT PROCESS..
    CHLID TIMER: 3
    CHLID TIMER: 4
    Child is over..
    Parent is over..status == 512
    Parent: WIFEXITED(status) == 1 //正常退出
    Parent: The return code WEXITSTATUS(status) == 2 //拿到子进程返回值
    展开全文
  •  default: //父进程  Message = "This is in the parent process,waiting the child finished........";  LoopVal = 5;  ExitCode = 15;  break;  }  for(LoopVal1=0;LoopVal1;LoopVal1++)  {  puts...

    #include <sys/types.h>
    #include<sys/wait.h>
    #include<unistd.h>
    #include<stdio.h>
    #include<stdlib.h>

    int main()
    {
      pid_t pid;                                  //记录fork()的返回值,用于区别父子进程
      char *Message;                              //用于记录输出信息
      int LoopVal;      //用于记录父子进程的循环次数
      int LoopVal1;      //用于循环
      int ExitCode;

      printf("the new fork starting\n");
      pid=fork();                                        //新建子进程
      switch(pid)
        {
        case -1:      //建立进程错误       
         printf("creat new fork error!");
         exit(1);
        case 0:                                           //子进程
          Message = "This is in the child process";
          LoopVal = 7;
          ExitCode = 25;
          break;
        default:                                         //父进程
          Message = "This is in the parent process,waiting the child finished........";
          LoopVal = 5;
          ExitCode = 15;
          break;
        }
      for(LoopVal1=0;LoopVal1<LoopVal;LoopVal1++)
        {
          puts(Message);
          sleep(1);
        }
      if(pid!=0)         //父进程
        {
          int StateVal;
          pid_t ChildPid;
          ChildPid = wait(&StateVal);         //用StateVal记录状态信息,wait返回的是子进程退出时,子进程的进程id。
          printf("The child has finished with  the PID of %d\n",ChildPid);
          if(WIFEXITED(StateVal))             //如果子进程正常结束,它就取一个非零值
       {

        //宏WEXITSTATUS(StateVal)是如果子进程正常结束,该宏函数的值为0,否则为非零值,与WIFEXITED(StateVal)刚好相反。
           printf("the child process has exit with code %d\n",WEXITSTATUS(StateVal));

                //如果WIFEXITED非零,它返回子进程的退出码
          }                                              

          else
              printf("the child has terminated abnormally\n");
        }                                                   //子进程非正常结束
        exit(ExitCode);
    }

     

     

     

    转载于:https://www.cnblogs.com/jasmine-Jobs/p/4425188.html

    展开全文
  • 一个父进程调用子进程后要对子进程的运行结果进行判断,子进程可以正常退出(exit()等)也可以其他情况退出(Ctrl C),但父进程要对子进程退出情况加以判断。 比如梨子: int main() { pid_t pid; int data=10; ...
  • 父进程等待子进程退出并收集子进程退出状态 子进程退出状态不被收集,会变成僵尸进程 举个例子 #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> int...
  • pid_t r_wait(int * stat_loc) { int revalue; while(((revalue = wait(stat_loc)) == -1) && (errno == EINTR));//如果等待的过程中被一个不可...服务退出之前父进程等待子进程的调用方法: while(r_wait(NULL)
  • int status; pid_t t = fork(); if(t){ waitpid(t, &status, 0); }else{ system("vi temp.txt");...//父进程和子进程均执行完毕后继续执行下去 分析过程: if和else还是选择分支。主要的原因是,fork(...
  • 父进程等待子进程退出并收集子进程退出状态 子进程退出状态不被收集,会变成僵尸进程 举个例子 #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> int...
  • ...当子进程先结束时,会向父进程发出信号,结束进程。(例如:父进程 sleep(15)) 如果写的有问题欢迎指出~ (注,文件名称命名错了semaphore是线程里的内容)
  • 这是个挺有趣的程序,我写了个例子同步了10个子线程,可以参考下:public class Test {static Test test = null;static int childNum = 0;synchronized static void decSem(){ childNum--; if(childNum == 0){ ...
  • fork函数一个进程可以调用fork()来复制自己,复制的时候这两个进程完全相同,之后便分道扬镳。...根据不同的返回值,可以判断当前运行的是子进程还是父进程父进程怎么等待子进程退出呢?父进程调用wait函数等待子进
  • 父进程等待子进程退出并收集子进程退出状态 1.父进程为什么要等待子进程退出? 创建子进程目的:------干活 我们要知道干活结束没。 子进程退出状态不被收集,变成僵尸进程 等待:wait,waitpid函数: #include &...
  • 【一个进程结束之后,就会变成僵尸进程,需要父进程替它收尸,1、如果其父进程在其死掉之前就已经死掉,则该进程就编程了孤儿进程,死后由init进程接管,死后也由init进程为其收尸 2、如果父进程没有调用wait函数...
  • 父进程 等待子进程初始化后才使用子进程_waitforinputidle 在进程中创建子进程是很常见的话题。常规的方法是用CreateProcess(),这个函数功能强大,使用起来也很方便。不过CreateProcess()或其他函数,如...
  • Linux下父进程异步等待子进程

    千次阅读 2017-07-17 10:00:56
      我们可以使用wait和waitpid函数清理僵死进程,父进程可以阻塞等待子进程结束,也可以非阻塞地查询是否有子进程结束等待清理(也就是轮询的方式)。采用第一种方式,父进程阻塞了就不能处理自己的工作了;采用第二种...
  • 父进程可以阻塞等待子进程结束,也可以非阻塞地查询是否有子进程结束等待清理(也就是轮询的方式)。 若采用阻塞等待方式,父进程就不能处理自己的工作了;采用非阻塞方式,父进程在处理自己工作的同时还要时不...
  • 在模拟实现之前,我们首先看一下以下几点 ...3、父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息 二、等待的方法 wait方法 pid_t wait(int *status); 返回值:成功返回被等待...
  • #include #include pid_t wait(int *status);... 孤儿进程:子进程还没退出,父进程就已经结束生命,此时的子进程为孤儿进程 Linux避免系统存在太多孤儿进程,init 进程收留孤儿进程,变成孤儿进程的父进程
  • linux 让父进程等待并检查子进程的退出状态 #include #include #include #include #include int main(int argv,char* argc[]){ pid_t pid; int n; char *message; int exit_code; printf("fork program ...
  • 父进程如果不等待子进程退出,在子进程之前就结束了自己的 “生命” ,此时的子进程便称为 孤儿进程。 Linux 系统为避免存在过多孤儿进程,设置了 init 进程收留孤儿进程,使其变为 孤儿进程的父进程。 init 进程...
  • Linux父进程对于子进程的异步等待

    千次阅读 2017-06-27 16:59:27
    父进程为什么等待子进程   Linux中,存在多进程、多线程的服务。 进程是如何产生、如何消失的? 首先,打开Linux虚拟机或者系统的时候,系统自己建立一个init进程,这是Linux系统的基础进程,然后init进程再根据...
  • 进程等待子进程结束

    千次阅读 2017-12-02 17:12:00
    子进程先于父进程退出时,如果父进程没有调用wait和waitpid函数,子进程就会进入僵死状态。如果父进程调用了wait或waitpid函数,就不会使子进程变为僵尸进程。这两个函数的声明如下: #include #include pid_t ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 83,566
精华内容 33,426
关键字:

父进程等待子进程结束