stask_struct内容及僵尸进程,孤儿进程的模拟实现

stack_struct结构是Linux内核的一种结构,它里面装着进程的各种状态信息。
下面是它里面一些重要的信息:

struct task_struct {

        //进程的运行时状态
        volatile long state;    /* -1 unrunnable, 0 runnable, >0 stopped */
        void *stack;   
        atomic_t usage;

        //进程当前的状态
        /*
        0x00000002表示进程正在被创建;

        0x00000004表示进程正准备退出;

        0x00000040 表示此进程被fork出,但是并没有执行exec;

        0x00000400表示此进程由于其他进程发送相关信号而被杀死 。
        */
        unsigned int flags;     /* per process flags, defined below */


        unsigned int ptrace;
        int on_rq;

        //表示此进程的运行优先级,prio表示动态优先级,根据static_prio和交互性奖罚算出
        //static_prio是进程的静态优先级,在进程创建时确定,范围从-20到19,越小优先级越高。
        int prio, static_prio, normal_prio;

        //进程的运行优先级
        unsigned int rt_priority;

        //list_head结构体
         struct list_head tasks;

        //mm_struct结构体,描述了进程内存的相关情况
         struct mm_struct *mm, *active_mm;

         /* per-thread vma caching */
         u32 vmacache_seqnum;
         struct vm_area_struct *vmacache[VMACACHE_SIZE];

        /* task state */
        //进程的状态参数
         int exit_state;
         int exit_code, exit_signal;

        //父进程退出后信号被发送
        int pdeath_signal;  /*  The signal sent when the parent dies  */ 

         /* scheduler bits, serialized by scheduler locks */
         unsigned sched_reset_on_fork:1;
         unsigned sched_contributes_to_load:1;
         unsigned sched_migrated:1;
         unsigned sched_remote_wakeup:1;
         unsigned :0; /* force alignment to the next boundary */

         /* unserialized, strictly 'current' */
         unsigned in_execve:1; /* bit to tell LSMs we're in execve */
         unsigned in_iowait:1;

         struct restart_block restart_block;

        //进程号
        pid_t pid;
        //进程组号
        pid_t tgid;


         //进程的亲身父亲
         struct task_struct __rcu *real_parent; /* real parent process */
         //进程的现在的父亲,可能为继父
         struct task_struct __rcu *parent; /* recipient of SIGCHLD, wait4() reports */
         //进程的孩子链表
         struct list_head children;      /* list of my children */
         //进程兄弟的链表
         struct list_head sibling;       /* linkage in my parent's children list */
         //主线程的进程描述符
         struct task_struct *group_leader;       /* threadgroup leader */

         /* PID/PID hash table linkage. */
         struct pid_link pids[PIDTYPE_MAX];

         //该进程的所有线程链表
         struct list_head thread_group;
         struct list_head thread_node;

        //该进程使用cpu时间的信息,utime是在用户态下执行的时间,stime是在内核态下执行的时间。
        cputime_t utime, stime;

        cputime_t gtime;
        struct prev_cputime prev_cputime;

        //启动时间,,只是时间基准不一样
        u64 start_time;         /* monotonic time in nsec */
        u64 real_start_time;    /* boot based time in nsec */

        struct task_cputime cputime_expires;

        //list_head的CPU时间
        struct list_head cpu_timers[3];

        //保存进程名字的数组,一般数组大小为15位
        char comm[TASK_COMM_LEN];

        /* file system info */
        //文件系统信息
        struct nameidata *nameidata;

        /* 文件系统信息计数*/
        int link_count, total_link_count;

        /* filesystem information */
        //文件系统相关信息结构体
         struct fs_struct *fs;

        /* open file information */
        //打开文件信息的结构体
         struct files_struct *files;

        /* namespaces */
         struct nsproxy *nsproxy;

        /* signal handlers */
        //信号相关信息的句柄
         struct signal_struct *signal;
         struct sighand_struct *sighand;

         struct callback_head *task_works;

         struct audit_context *audit_context;

         struct seccomp seccomp;

        /* Thread group tracking */
         u32 parent_exec_id;
         u32 self_exec_id;

        /* journalling filesystem info */
         void *journal_info;

        /* VM state */
         struct reclaim_state *reclaim_state;

         struct backing_dev_info *backing_dev_info;

         struct io_context *io_context;

         unsigned long ptrace_message;
         siginfo_t *last_siginfo; /* For ptrace use.  */


         /*
          * time slack values; these are used to round up poll() and
          * select() etc timeout values. These are in nanoseconds.
          */
         //松弛时间值,用来记录select和poll的超时时间,单位为ns
         u64 timer_slack_ns;
         u64 default_timer_slack_ns;


        /* CPU-specific state of this task */
        //该进程在特定CPU下的状态
        struct thread_struct thread;

};

我们知道僵尸进程是很难杀死的,我们要避免产生僵尸进程。
僵尸进程的产生,是子进程先死,而父进程还在,父进程并没有收到关于子进程死亡的信息,在程序结束后,都没有收回子进程的空间,以致浪费空间资源。使用kill也删除不了僵尸进程,但是可以使用wait,waitpid来处理僵尸进程。
下面是模拟产生僵尸进程的代码:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

int main()
{
        pid_t pid = fork();
        if(pid == 0){
                printf("child\n");
                exit(0);
        }else if(pid > 0){
                printf("parent\n");
                sleep(30);
        }
}

孤儿进程是,父进程先死,而子进程还在。但是子进程会被1号进程收养,1号进程成了子进程的父进程,子进程的资源回收都会通过1号进程去控制。

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

int main()
{
        pid_t pid = fork();
        if(pid == 0){
                printf("child\n");
                sleep(30);
        }else if(pid > 0){
                printf("parent\n");
                exit(0);
        }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值