LInux多进程开发

/*
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
作用:创建子进程
    返回值:
        fork()返回值会返回两次,一次是在父进程中,一次是在子进程中
        在父进程中返回创建的子进程的ID,
        在子进程中,返回0
        如何区分父进程和子进程,通过fork的返回值
        在父进程中返回-1,表示创建子进程失败,并且设置errno


    父子进程之间的关系:
    区别:
        1.fork()函数的返回值不同
            父进程中:>0,返回子进程的PID
            子进程中:=0
        2.pcb中的一些数据
            当前进程的id pid
            当前进程的父进程的id ppid
            信号集
        共同点:
            某些状态下,子进程刚被创建出来,还没有执行任何的写数据操作
                -用户区的数据
                -文件描述符表
            父子进程对变量是否是共享的
                -刚开始是一样的,如果修改类数据,就不共享了
                读时共享(子进程刚创建),写时拷贝
                父子进程之间不能用变量进行通信,它们之间互不影响

*/
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main()
{

    int num =10;
    //创建子进程
    pid_t pid = fork();//pid_t本质上是int类型的
    //判断是父进程还是子进程
    if(pid>0){
        printf("pid : %d\n", pid);
        //如果大于0,返回的是创建的子进程的id,当前是父进程
        printf("i am parent process,pid : %d, ppid:%d\n",getpid(),getppid());
        printf("parent num: %d\n",num);
        num+=10;
        printf("parent num+=10: %d\n",num);
    }else if(pid ==  0)
    {
        //当前是子进程
        printf("i am child process, pid :%d,ppid : %d\n",getpid(),getppid());
        printf("child num: %d\n",num);
        num+=100;
        printf("child num+=100: %d\n",num);
    }
    for(int i =0;i<3;i++)//默认父子进程都会去执行
    {
        printf("i : %d\n", i);
        sleep(1);

    }
    return 0;
}

LInux多进程开发

exec函数族

可执行文件的用户区去替换进程中的用户区,一般情况下会创建一个子进程,在子进程创建exec函数族中的函数

 LInux多进程开发

 

 LInux多进程开发

 

查看execl

 LInux多进程开发

LInux多进程开发

 

 子进程被替换掉

 LInux多进程开发

 

 execlp

/*#include <unistd.h>

       extern char **environ;

       int execlp(const char *file, const char *arg, ...);
        -会到环境变量中查找指定的可执行文件,如果找到了就执行,找不到就
            参数:-file:需要指定的执行的可执行文件的文件名
                a.out    ps
                  -arg:是执行可执行文件所需要的参数列表
                    第一个参数一般没有什么作用,为了方便一般写的执行的参数的名称,从第二个人参数开始往后,就是程序执行所需要的参数列表
                    参数最后需要以NULL结束(哨兵)
             返回值:-仅仅在出错的时候返回,返回-1,并且设置errno
             如果调用成功,就没有返回值
                    
*/
#include <unistd.h>
#include <stdio.h>

int main()
{
    //创建一个子进程在子进程中执行exec函数族中的函数

    pid_t pid =fork();
    if(pid >0){
        //父进程
        printf("i am parent process,pid : %d\n",getpid());
        sleep(1);
    }else if(pid == 0)
    {
        //子进程
        execlp("ps","ps","aux",NULL);
        printf("i am child process , pid:%d\n",getpid());
    }
    for(int i =0;i<3;i++){
        printf("i=%d , pid = %d\n",i,getpid());
    }

    return 0;
}

第一个参数是可执行程序的程序名,第二个参数

 LInux多进程开发

 

 进程控制

fork函数  读时共享,写时复制      主要目的是降低内存的使用

LInux多进程开发

 

 

子进程退出,父进程能得到子进程退出的状态       父进程有义务回收子进程的资源

LInux多进程开发

 

#include <stdlib.h>
#include<unistd.h>
#include <stdio.h>
int main()
{
    printf("hello\n");
    printf("world");

    exit(0);

    return 0;  //和exit是一样的,都表示进程退出

}

结果  exit()       从图中两者的功能对比可以知 

LInux多进程开发

 将exit()改成_exit()后      world在缓冲区里

LInux多进程开发

 

 孤儿进程

父进程运行结束,子进程还在运行,这样的子进程称为孤儿进程

? 每当出现一个孤儿进程的时候,内核就把孤儿进程的父进程设置为 init ,而 init进程会循环地 wait() 它的已经退出的子进程。这样,当一个孤儿进程凄凉地结束了其生命周期的时候,init 进程就会代表出面处理它的一切善后工作。

孤儿进程并不会有什么危害

如下,1领养了孤儿进程 ,由1进程回收资源

LInux多进程开发

 

 父进程结束后,显示了一个终端(回到前台)

为什么都显示在终端?父子进程的内核去的一些部分是共享的   文件描述符表前三个(0,1,2)标准输入,输出,错误 

僵尸进程

? 每个进程结束之后, 都会释放自己地址空间中的用户区数据,内核区的 PCB 没有办法自己释放掉,需要父进程去释放。
? 进程终止时,父进程尚未回收,子进程残留资源(PCB)存放于内核中,变成僵尸
(Zombie)进程。

僵尸进程不能被kii -9杀死

LInux多进程开发

 

LInux多进程开发

上一篇:Linux命令


下一篇:Linux系统目录树结构