3.4.8.waitpid(等待指定子进程的pid)介绍

3.4.8.waitpid(等待指定子进程的pid)介绍waitpid 和 wait 都是用于父进程回收子进程的系统调用 waitpid 提供了更灵活的选项 如指定 PID 非阻塞模式等

大家好,欢迎来到IT知识分享网。

3.4.8.waitpid介绍
3.4.8.1、waitpid和wait差别

相同点 是功能, 不同点是 使用 方法
(1)基本功能一样,都是用来回收子进程
(2)waitpid可以回收指定 PID 的子进程
(3)waitpid可以阻塞式或非阻塞式两种工作模式

3.4.8.2、waitpid原型介绍
(1)参数
(2)返回值

3.4.8.waitpid(等待指定子进程的pid)介绍
3.4.8.3、代码实例
(1)使用waitpid实现wait的效果
ret = waitpid(-1, &status, 0);      -1表示不等待某个特定PID的子进程而是回收任意一个子进程,0表示用默认的方式(阻塞式)来进行等待,返回值ret是本次回收的子进程的PID
(2)ret = waitpid(pid, &status, 0);        等待回收PID为pid的这个子进程,如果当前进程并没有一个ID号为pid的子进程,则返回值为-1;如果成功回收了pid这个子进程则返回值为回收的进程的PID
(3)ret = waitpid(pid, &status, WNOHANG);这种表示父进程要非阻塞式的回收子进程。此时如果父进程执行waitpid时子进程已经先结束等待回收则waitpid直接回收成功,返回值是回收的子进程的PID;如果父进程waitpid时子进程尚未结束则父进程立刻返回(非阻塞),但是返回值为0(表示回收不成功)。

 代码:

ret = waitpid(-1,&status,0); /* waitpid ,-1表示不管是那个子进程都回收 ,0 表示 阻塞式 */

只是 更改了 这一句,其他的 和 wait 都一样,效果也一样

#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main(void) { /* 接收 fork 的返回值 */ pid_t p1 = -1; /* 接收 wait waitpid 的返回值 */ pid_t ret = -1; /* wait waitpid 传参,进程状态信息 */ int status = -1; p1 = fork(); //fork 函数返回 2 次 : 等于0 是子进程, 大于0是父进程 if(0 == p1) { /* 这里一定是 子进程 , 子进程先结束,成为僵尸进程 ,一定要保证子进程先结束 */ printf("子进程 child pid = %d \n", getpid()); return 99; } else if (p1 > 0) { /* 这里一定是 父进程 */ ret = waitpid(-1,&status,0); /* waitpid ,-1表示不管是那个子进程都回收 ,0 表示 阻塞式 */ printf("子进程已经被回收,子进程pid = %d \n", ret); printf("子进程是否正常退出:%d \n", WIFEXITED(status)); /* WIFEXITED 判断是否正常退出 */ printf("子进程是否 非正常退出:%d \n", WIFSIGNALED(status)); /* WIFSIGNALED 判断是否 非正常退出 */ printf("子进程正常终止情况下的  进程返回值:%d \n", WEXITSTATUS(status)); /* WEXITSTATUS 正常终止情况下的  进程返回值 */ } else { /* 这里一定是 fork出错了 */ perror("fork"); return -1; } return 0; } 

运行结果:

3.4.8.waitpid(等待指定子进程的pid)介绍

 实例 2 , waitpid  用指定 pid 回收 子进程

#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main(void) { /* 接收 fork 的返回值 */ pid_t p1 = -1; /* 接收 wait waitpid 的返回值 */ pid_t ret = -1; /* wait waitpid 传参,进程状态信息 */ int status = -1; p1 = fork(); //fork 函数返回 2 次 : 等于0 是子进程, 大于0是父进程 if(0 == p1) { /* 这里一定是 子进程 , 子进程先结束,成为僵尸进程 ,一定要保证子进程先结束 */ printf("子进程 child pid = %d \n", getpid()); return 99; } else if (p1 > 0) { printf(" 父进程中打印 子进程id = %d \n ",p1); /* 这里一定是 父进程 */ /* 这里一定是 父进程 */ ret = waitpid(p1,&status,0); /* waitpid ,-1表示不管是那个子进程都回收 ,0 表示 阻塞式 */ printf("子进程已经被回收,子进程pid = %d \n", ret); printf("子进程是否正常退出:%d \n", WIFEXITED(status)); /* WIFEXITED 判断是否正常退出 */ printf("子进程是否 非正常退出:%d \n", WIFSIGNALED(status)); /* WIFSIGNALED 判断是否 非正常退出 */ printf("子进程正常终止情况下的  进程返回值:%d \n", WEXITSTATUS(status)); /* WEXITSTATUS 正常终止情况下的  进程返回值 */ } else { /* 这里一定是 fork出错了 */ perror("fork"); return -1; } return 0; } 

运行结果:

3.4.8.waitpid(等待指定子进程的pid)介绍

 实例 3 ,如果传一个 错误的 pid  , waitpid会返回 什么呢?????

传一个 错误的 pid  : p1+6

ret = waitpid(p1+6,&status,0); /* waitpid ,-1表示不管是那个子进程都回收 ,0 表示 阻塞式 */

运行结果:

3.4.8.waitpid(等待指定子进程的pid)介绍

实例 4  waitpid   非阻塞式 回收 WNOHANG 

ret = waitpid(p1,&status,WNOHANG);  /* waitpid ,-1表示不管是那个子进程都回收 ,WNOHANG  表示 非阻塞式 */

代码:

#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main(void) { /* 接收 fork 的返回值 */ pid_t p1 = -1; /* 接收 wait waitpid 的返回值 */ pid_t ret = -1; /* wait waitpid 传参,进程状态信息 */ int status = -1; p1 = fork(); //fork 函数返回 2 次 : 等于0 是子进程, 大于0是父进程 if(0 == p1) { /* 这里一定是 子进程 , 为了 保证 父进程 先执行 waitpid 非阻塞式 回收 ,子进程sleep , 先让父进程执行 */ sleep(1); /* 这里一定是 子进程 , 子进程先结束,成为僵尸进程 ,一定要保证子进程先结束 */ printf("子进程 child pid = %d \n", getpid()); return 99; } else if (p1 > 0) { printf(" 父进程中打印 子进程id = %d \n ",p1); /* 这里一定是 父进程 */ /* 这里一定是 父进程 */ ret = waitpid(p1,&status,WNOHANG); /* waitpid ,-1表示不管是那个子进程都回收 ,WNOHANG 表示 非阻塞式 */ printf("子进程已经被回收,子进程pid = %d \n", ret); printf("子进程是否正常退出:%d \n", WIFEXITED(status)); /* WIFEXITED 判断是否正常退出 */ printf("子进程是否 非正常退出:%d \n", WIFSIGNALED(status)); /* WIFSIGNALED 判断是否 非正常退出 */ printf("子进程正常终止情况下的  进程返回值:%d \n", WEXITSTATUS(status)); /* WEXITSTATUS 正常终止情况下的  进程返回值 */ } else { /* 这里一定是 fork出错了 */ perror("fork"); return -1; } return 0; } 

运行结果:

3.4.8.waitpid(等待指定子进程的pid)介绍

3.4.8.waitpid(等待指定子进程的pid)介绍 

 实例 4  waitpid   非阻塞式 回收 WNOHANG 

把 sleep 加入到 父进程 ,让子进程先结束,子进程进入僵尸进程后 ,父进程 去回收

代码:

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

int main(void)
{

    /* 接收 fork 的返回值 */
    pid_t p1 = -1;
    /* 接收 wait waitpid 的返回值 */
    pid_t ret = -1;
    /*  wait waitpid 传参,进程状态信息 */
    int status = -1;
    
    
    p1 = fork();  //fork 函数返回 2 次  : 等于0 是子进程, 大于0是父进程
    
    if(0 == p1)
    {

        /* 这里一定是 子进程 ,   子进程先结束,成为僵尸进程 ,一定要保证子进程先结束 */
        printf(“子进程 child pid = %d \n”, getpid()); 
        return  99;
    }    
    else if (p1 > 0)
    {

         /*  父进程 加入 sleep */
        sleep(1);
        printf(” 父进程中打印 子进程id = %d \n “,p1);                   /* 这里一定是 父进程 */
        /* 这里一定是 父进程 */
        ret = waitpid(p1,&status,WNOHANG);  /* waitpid ,-1表示不管是那个子进程都回收 ,WNOHANG  表示 非阻塞式 */
        printf(“子进程已经被回收,子进程pid = %d \n”, ret);
        printf(“子进程是否正常退出:%d \n”, WIFEXITED(status));  /* WIFEXITED  判断是否正常退出 */
        printf(“子进程是否 非正常退出:%d \n”, WIFSIGNALED(status));  /* WIFSIGNALED 判断是否 非正常退出 */
        printf(“子进程正常终止情况下的  进程返回值:%d \n”, WEXITSTATUS(status));  /* WEXITSTATUS 正常终止情况下的  进程返回值 */
    }
    else
    {

        /* 这里一定是 fork出错了  */
        perror(“fork”);
        return -1;
    }
    

    
    
    return 0;
}
运行结果:

3.4.8.waitpid(等待指定子进程的pid)介绍

 

3.4.8.4、竟态初步引入
(1)竟态全称是:竞争状态,多进程环境下,多个进程同时抢占系统资源(内存、CPU、文件IO)

进程1 读1.txt, 进程2 也同时读1.txt

  如果 没有 sleep 我们就不确定 到底是 父进程先 结束,还是 子进程先结束!!!

(3)写程序当然不希望程序运行的结果不确定,所以我们写程序时要尽量消灭竞争状态。操作系统给我们提供了一系列的消灭竟态的机制我们需要做的是在合适的地方使用合适的方法来消灭竟态。
 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/119699.html

(0)
上一篇 2024-11-19 09:15
下一篇 2024-11-19 09:26

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信