linux环境下的进程

进程

:程序的一个执行实例,正在运行的程序等,同时是分配系统资源的基本单位

描述进程(PCB):在linux环境下用task_struct的结构体来描述进程,该结构体包含了进程所需要的所有信息。
task_struct:是内核中linux下的一种数据结构,它会被装载在RAM下包含进程的信息。
内容分类:

标识符:进程的唯一标识符,区别于其他进程
状态:任务状态,退出代码,退出信号
优先级:此进程相比较其他进程的优先级
程序计数器:即将执行的下一条指令的地址
内存指针:包括程序代码以及和进程相关信息的指针,以及其他共享内存块的指针
上下文数据:进程执行时cpu中寄存器中的数据
I/O信息:包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表
记账信息:辅助进程调度

进程状态

volatile long state//说明该进程是否可以执行,还是可中断等信息
#define TASK_RUNNING        0  //正在运行或者在就绪队列中准备运行的进程
#define TASK_INTERRUPTIBLE  1  //处于等待队列中的进程,直到某个条件有效时进入就绪队列
#define TASK_UNINTERRUPTIBLE    2  //处于等待队列中的进程,待资源有效时唤醒,不可由其他进程通过信号或定时中断唤醒
#define __TASK_STOPPED      4  //进程被暂停,通过其他进程的信号才能唤醒
#define __TASK_TRACED       8  //表示进程被Debug追踪
/* in tsk->exit_state */  
#define EXIT_ZOMBIE     16  //僵尸状态的进程,表示进程被终止,但父进程还没获得其终止信息
#define EXIT_DEAD       32//进程死亡 
/* in tsk->state again */  
#define TASK_DEAD       64  //死亡
#define TASK_WAKEKILL       128  //唤醒并杀死进程
#define TASK_WAKING     256//唤醒进程

2.进程的标识符

pid_t pid;//进程的唯一标识符
pid_t tgid;//线程组的领头线程的pid

在linux环境下,一个线程组所有的线程使用和该线程组的领头线程相同的pid,并存放在tgid中。


进程的标记符

unsigned int flags;
flags反映进程的状态信息,用于内核识别该进程的当前状态

常用的状态
#define PF_FORKNOEXEC   0x00000040      //表示进程刚被创建,还没执行
#define PF_SUPERPRIV    0x00000100      //表示该进程有超级用户特权
#define PF_SIGNALED     0x00000400      //表示进程被信号杀出
#define PF_EXITING      0x00000004      //表示进程开始退出

进程之间的亲属关系

struct task_struct *real_parent;
struct task_struct *parent;
struct list_head children;
struct list_head sibling;
struct task_struct *group_leader;

real_parent指向其父进程,如果创建它的父进程不存在,则指向pid为1的init进程。
parent指向其父进程,当它终止时,必须向它父进程发出信号,值通常与real_parent相同。
children表示链表的头部,链表的所有元素都是其子进程。
sibling用于把当前进程插入到兄弟链表中。
group_leader指向其所在进程组的领头进程。


进程的调度信息

int prio,static_prio, normal_prio;
unsigned int rt_priority;
const struct sched_class *sched_class;
struct sched_entity se;
struct sched_rt_entity rt;
unsigned int policy;

stati_prio用于保存静态优先级,可以通过nice系统调用来进行修改
rt_priority用于保存实时优先级。
normal_prio的值取决于静态优先级和调度决策。
prio用于保存动态优先级。
policy表示进程的调度策略。
进程的调度算法

#define SCHED_NORMAL  0//按照优先级进行调度
#define SCHED_FIFO  1//先进先服务的调度算法
#define SCHED_RR    2//时间片轮转的调度算法
#define SCHED_BATCH 3//用于非交互的CPU消耗型的进程
#define SCHED_IDLE  5//系统负载很低时的调度
#define SCHED_RESET_ON_FORK 0x40000000

创建进程
我们分别可以用fork()和vfork()来创建进程,新创建的进程为子进程,原进程为父进程,代码实现如下

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

int main()
{
    int ret=fork();
    if(ret<0)
    perror("fork");
    return 1;
    else if(ret==0)
    {
    printf("child:%d!,ret:%d\n",getpid(),ret);
    }else{
    printf("father:%d!,ret:%d\n",getpid(),ret);
    }
    sleep(1);
    return 0;
}

僵尸进程:当进程退出,父进程没有接收到子进程退出信号

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

int main()
{
    pid_t id =fork();
    if(id<0)
    perror("fork");
    return 1;
    else if(id==0)
    {
        printf("child:%d is begin z\n",getpid());
        sleep(5);
        exit(EXIT_SUCCESS);
    }
    else{
    printf("parent;%d is sleeping\n",getpid());
    sleep(30);
    }
    return 0;
}   

孤儿进程:父进程先退出,子进程称之为“孤儿进程”。

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

int main()
{
    pid_t id =fork();
    if(id<0)
    {
    perror("fork");
    return 1;
    }
    else if(id==0)
    {
    printf("child,pid:%d\n",getpid());
    sleep(10);
    }
    else
    {
    printf("parent,pid:%d\n",getpid());
    sleep(3);
    exit(0);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qqkb1016/article/details/80040650