当前位置:   article > 正文

Linux c frok出三个子进程各做所事,父进程回收所有子进程(fork、execl、execlp、wait、waitpid)_linux fork()函数子进程做不同的事情

linux fork()函数子进程做不同的事情

1、函数介绍

1、fork()函数:创建子进程

pid_t fork(void);
无参数
返回值:
	(pid_t 类型其实就是一个整型)
	成功:
		父进程返回,子进程id
		子进程返回,0
	
	失败:
	 	-1 设置errno
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2、execl()函数,execlp()函数:执行可执行文件,和系统命令

int execl(char* path,const char *arg,...);
参数:
	path	可执行文件路径
	arg		可以是多个,可以通过下面例子体现
返回值:
	成功:不返回
	失败:-1 errno


int execlp(char* file,const char *arg,...);
参数:
	file	系统命令名
	arg		可以是多个,可以通过下面例子体现
返回值:
	成功:不返回
	失败:-1 errno

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

3、wait函数和waitpid 回收子进程

每一个进程结束,都会在内存中残留一个PCB进程控制块,方便回收他的状态
pid_t wait(int* status);
参数:	
	status 传出参数,回收成功后,会返回进程的退出状态

返回值:
    成功:子进程id
    失败:-1


pid_t waitpid(pid_t pid,int *status,int options);
参数:
    pid 指定某一个进程pid
    status 传出参数,会返回进程状态
    options WNOHANG不等待非堵塞
第一个参数传入值的作用
-1表示任意子进程
0 表示同组的所有进程
<-1 回收指定进程组内的任意子进程

返回值:
    >0 表示成功回收的子进程pid
    0  函数调用时,参数3指定WNOHANG,并且,没有子进程结束
    -1 失败errno

总结:
    wait、waitpid 一次调用,回收一个子进程,回收多个需要用while
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

2、需求,代码

使用fork创建三个子进程,
第一个子进程执行 ls -l 命令,
第二个子进程执行当前目录下的./test 可执行文件
第三个子进程打印文字到屏幕
父进程堵塞回收所有子进程 (第一种回收方式)
父进程不堵塞回收所有子进程(第二种回收方式)

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

void sys_error(const char* str)
{
    perror(str);
    exit(1);
}

int main(void)
{
    pid_t pid;
    int i;
    // 循环创建三个子进程
    for(i=0;i<3;i++)
    {	// 返回0表示是,子进程就退出这个循环,不然子进程又会创建子进程
        if((pid = fork())==0)
            break;
        if(pid == -1)
            sys_error("fork error");
    }
    
    if(pid == 0)	// pid为0,表示子进程
    {	
        switch(i)
        {
            case 0:
                printf("111111111111111111\n");
                sleep(1);	// 方便看效果
                execlp("ls","ls","-l",NULL);
                // 要是上面语句不报错,这条不会执行,因为他不会回来了
                printf("111111111111111111\n");
                break;
            case 1:
                printf("2222222222222222222\n");
                sleep(1);	// 方便看效果
                execl("./test2","./test2",NULL);
                // 要是上面语句不报错,这条不会执行,因为他不会回来了
                printf("2222222222222222222\n");
                break;
            case 2:
                printf("333333333333333333\n");
                sleep(1);	// 方便看效果
                printf("子进程三打印\n");
                printf("33333333333333333\n");
                break;
        }
    }
    else if(pid >0)
    {
        int status,wpid;
        while ((wpid=waitpid(-1,&status,0))!= -1)    //堵塞
        {
             printf("wpid = %d\n",wpid);
        }
        
      //  while ((wpid=waitpid(-1,&status,WNOHANG))!= -1) // 不堵塞
      //  {
      //      printf("wpid = %d\n",wpid);
      //  }

        // sleep(2);
        printf("我是父进程\n");
    }

    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69

在这里插入图片描述

通过打印信息可以看出,他们不是一个进程执行完在执行另一个,他们会争取cpu

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/273223
推荐阅读
相关标签
  

闽ICP备14008679号