孤儿进程、僵尸进程、守护进程

    上次讲了关于线程的一些操作,这次讲一下进程,进程是程序运行的真正实例,就linux而言,进程结构可以分为三部分,代码段、数据段和堆栈段。余下的就不进行科普了

    进程的创建通过fork来搞定,由于创建的进程会完美copy父进程的数据,数据段和堆栈段(说copy有些不好,毕竟现在操作系统实现了一种“写时复制”的机制,只有子进程修改了某些内容时,操作系统才会开辟空间把修改的内容从父进程copy过来,想一想就知道主要很省空间),所以调用一次fork会返回两次(堆栈段一样,可以看成父子进程执行的深度一样),父进程返回儿子的pid,子进程返回0,然后通过下面的操作就可以实现父子进程执行不同的操作。


  

pid = fork();
if(0 > fork){
    printf("Create error\n");
    exit(0);
}

else if(0 == fork){
    printf("Parent process");
    //do
    exit(0)
}

printf("child process!");
//do

    1、孤儿进程:爸比死掉的进程,如果创建的子进程的父进程在子进程结束之前挂掉了,那么子进程就成为孤儿进程,被init进程收养,孤儿进程实质上没什么危害。

    2、僵尸进程:爸比还在,儿子挂掉了,但是爸比没有给儿子收尸(通过wait或者是waitpid函数),儿子就变成僵尸了。这里有一个小知识,子进程执行完了,按道理而言他的一切都应该被销毁,不应该留下一些什么。但是实际上一个进程执行完了,操作系统是会回收他的资源,但是保留了一个数据结构Zombie,记录这个进程是什么状态,怎么挂掉的,就像是某人挂了会留下一具尸体,然后验尸官可以得到你的死因。如果是仅仅占用些资源没啥大不了的,关键是僵尸进程还把进程号pid一拿着(死不瞑目啊),而系统的进程号又是有限的,僵尸进程多了,系统便不能创建新的进程了。通过上面所讲,可以知道为什么子进程挂了,父进程还是能够得到他的状态信息,通过上面的两个函数可以回收Zombie这部分资源。要不然只有等父进程挂了,由init进程收养,init会定期清理僵尸进程。

    在linux下使用ps命令,看到-Z标志可以判定该进程是一个僵尸进程

    3、守护进程:终端写多了就知道,一般开一个进程,打开了一个窗口,把窗口关了,进程也就结束了。而守护进程则是脱离于终端并且在在后台运行的进程,创建守护进程如下;

①创建子进程,父进程退出

②在子进程中创建新的会话——setsid()

使用系统函数setsid()建立新会话,并担任会话组的组长,让进程摆脱原会话、原进程组、原控制终端的控制,使进程完全独立出来,摆脱其它进程控制。

③改变当前工作目录为根目录:子进程进程父进程的当前工作目录,在实际运行中会对以后的的使用造成麻烦

④重设文件掩码:继承了父进程的文件掩码,对于有些操作不方便

⑤关闭文件描述符:对于继承自父进程子进程不需要的文件,关掉节约系统资源


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

#define MAXFILE 65535

int main(void)
{
    pid_t pid;
    int i, fd, len;
    char buf[100] = "Daemon process write!\n";
    len = strlen(buf);


    pid = fork();
    if(0 > pid){
        sleep(10);
        printf("error");

    }else if(0 < pid){
        printf("Parent process!");
        sleep(2);
        exit(0);
    }

    printf("a daemon process!");
    sleep(2);

    //create a daemon process
    setsid();        //1建立新会话
    chdir("/");        //2改变工作目录为根目录
    umask(0);        //3重设文件权限掩码
    for(i = 0; i < MAXFILE; ++i)
        close(i);        //4关闭文件描述符

    while(1){
        if(fd = open("//home/sakura/Desktop/daemon.log", O_CREAT|O_WRONLY|O_APPEND, 0600) <0 ){
            perror("open");
            exit(1);
        }
        write(fd, buf, len + 1);
        close(fd);
        sleep(10);
    }

    printf("Over");
    sleep(10);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37925512/article/details/80546656