• <div id="0yoao"><tr id="0yoao"></tr></div>
    <dl id="0yoao"></dl>
  • <sup id="0yoao"></sup>
    <div id="0yoao"><tr id="0yoao"></tr></div>
  • <div id="0yoao"><tr id="0yoao"></tr></div>
  • ?

    process identification

    作者:linuxer 发布于:2014-3-26 12:28 分类:进程管理

    一、概述

    本文主要描述在linux kernel中如何标识一个或者一组和进程(线程)相关的实体,包括:

    1、进程ID(线程组ID

    2、线程ID

    3、进程组ID

    4Session ID

    需要强调的是本文focusidentification,很多展开的内容会有一系列文档描述。

     

    二、什么是进程ID(线程组ID

    一般而言,我?#23884;?#20250;定义进程是一个正在执行的程序或者是一个程序的运行实例。程序是一个静态的概念,是存储在磁盘?#31995;?#20108;进制可执行文件,包括程序代码和数据(正文段、数据段等)。当程序运行起来成为进程的时候,单纯的程序代码则不能清楚的描述进程,它还需要若干数据结构来描述程序的执行状态(?#24067;?#19978;下文和软件上下文)以及拥有的资源(如地址空间、打开的文件描述符等)。从内核的?#23884;?#30475;,进程是一个和系统资源(CPU timememory等)分配相关的实体。

    POSIX标准中,系统定义了getpid函数来获取一个进程的process ID。在linux kernel中,定义如下:

    asmlinkage long sys_getpid(void)

    {

           return current->tgid;

    }

    从字面上看task_struct中的tgidthread group ID,也就是线程组ID,在linux kernel中,进程是有一个或者多个thread组成(POSIX规定多个thread要共享一个进程ID)。对于linux kernel,每一个thread分配一个task_struct(其中有一个pid的标识),这和大部分的kernel处理不一样,其他的kernel针对一个进程分配一个task_struct,在该task_struct中嵌入了属于该进程的各个线程的数据。正因为如此,linux kernel创建一个线程组的概念来?#25104;?#21040;POSIX中的进程概念。

    多线程的进?#35752;?#31532;一个线程(主线程,group leader)的pid等于tgid,之后,该线程组中的线程都有自己的pid,但是共享tgid,也就是传统意义?#31995;?#36827;程IDtask_struct有一个group_leader成员,指向该task的thread group leader,对于group leader,该成员指向自己的task_struct数据结构。

     

    三、什么是线程ID

    线程是进?#35752;?#30340;一个实体,是被系统独立调度和分派的基本单位,线程自己不独立拥有系统资源,它是与同属一个进程的其它线程共享进程所拥有的全部资源(如地址空间、文件描述符和信号处理)。这首先表现在?#26680;?#26377;线程都具有相同的地址空间(进程的地址空间),这意味着,线程可以访问该地址空间的每一个虚地址;此外,还可以访?#24335;?#31243;所拥有的已打开文件、定时器、信号量等资源。进程是资源管理的最小单元,而线程是程序执行的最小单元。除了共享的进程资源,进?#35752;?#30340;各个线程也属于自己的资源,具体包括:stackPC counterCPU寄存器。

    每个线程应该有自己的ID,就是线程ID,在linux kernel中,每一个thread分配一个task_struct,该结构中的pid成?#26412;?#26159;线程ID。在POSIX标准中,定义了pthread_self来获取线程IDlinux kernel采用了gettid的系统调用来获取调用者的线程ID。在linux kernel中,定义如下:

    asmlinkage long sys_gettid(void)

    {

           return current->pid;

    }

    POSIX规定线程ID在所属进?#35752;?#26159;唯一的,不过在linux kernel的实现中,thread ID是全系统唯一的,当然,考虑到可移植性,Application software不应该假设这一点。

     

    四、什么是进程组ID

    每个进程属于一个进程组,每个进程组有一个Leader进程,也就是进程ID等于进程组ID的那个进程。进程组有生命周期,它的生命周期开始于进程组leader创建进程组,结束于进程组内的最后一个进程离开进程组(可能是进程退出, 或加入其他进程组)。进程组概念的提出主要是由于:

    1、和job control相关,关于job control,后续会专门的文档详细描述。

    2 Signal可以发送给进程组的每一个进程(job control也使用这个特性。例如job control signal会被送给job(进程组)中的每一个进程)

    3、进程同步的时候,父进程可以wait for进程组中的任何一个进程

    POSIX标准中,系统定义了getpgid函数来获取一个进程的process group ID。在linux kernel中,定义如下:

    asmlinkage long sys_getpgid(pid_t pid)

    {

           if (!pid) {

            //如果pid等于0,那么需要获取当前进程的进程组ID

                  return process_group(current);

        }

           else {

    //否则,获取pid标识的那个进程对应的进程组ID

                  int retval;

                  struct task_struct *p;

     

                  read_lock(&tasklist_lock);

                  p = find_task_by_pid(pid);

     

                  retval = -ESRCH;

                  if (p) {

                //是否有权利获取其他进程的进程组ID

                         retval = security_task_getpgid(p);

                         if (!retval)

                                retval = process_group(p);

                  }

                  read_unlock(&tasklist_lock);

                  return retval;

           }

    }

     

    static inline pid_t process_group(struct task_struct *tsk)

    {

           return tsk->signal->pgrp;

    }

    task_struct中的signal中的pgrp成员标识了进程组ID。从pgrp的位置来看,进程组应该是和信号处理相关的,后续会专门的文档详细描述。

     

    五、Session ID

    和进程属于进程组类似,每个进程组都属于一个session,每个session有一个Leader进程,也就是创建session的那个进程,session leaderID就等于该sessionIDSession概念的提出和用户登录以及终端编程相关,后续会专门的文档详细描述。

    POSIX标准中,系统定义了getsid函数来获取session leader进程的process group ID。如果指定的PID不是session leader,将返回错误,但是在linux kernel中没有完全遵守这个规定,getsid函数总是能返回指定PIDsession ID,无论该PID指向的进程是否是session leader,具体定义如下:

    asmlinkage long sys_getsid(pid_t pid)

    {

           if (!pid) {

            //如果pid等于0,那么需要获取当前进程的进程组ID

                  return process_session(current);

        }

           else {

    //否则,获取pid标识的那个进程对应的进程组ID

                  int retval;

                  struct task_struct *p;

     

                  read_lock(&tasklist_lock);

                  p = find_task_by_pid(pid);

     

                  retval = -ESRCH;

                  if (p) {

                         retval = security_task_getsid(p);

                         if (!retval)

                                retval = process_session(p);

                  }

                  read_unlock(&tasklist_lock);

                  return retval;

           }

    }

    static inline pid_t process_session(struct task_struct *tsk)

    {

           return signal_session(tsk->signal);

    }

    static inline pid_t signal_session(struct signal_struct *sig)

    {

           return sig->__session;

    }

    task_struct中的signal中的__session成员标识了进程组ID。从__session的位置来看,session应该也是和信号处理相关的,后续会详细描述。


    原创文章,转发请注明出处。蜗窝科技,www.71402172.com

    标签: process management

    评论:

    王举
    2019-03-21 15:41
    session和进程组是不是一一对应的?
    REGA
    2016-10-19 16:20
    能否请linuxer简单的总结一下在linux中process、thread、task之间的关系和区别呢?
    linuxer
    2016-10-19 19:22
    @REGA:在linux中,thread<----->struct task_struct,process<----->共享某些资源的若干struct task_struct,这些thread属于一个线程组。

    task是一个不太规范的用语,在很多rtos中使用,类似与线程。
    justin
    2015-10-21 16:53
    一直有疑惑,linux中是不是没有进程、线程的概念,只有task的说法?
    linuxer
    2015-10-21 19:37
    @justin:都有的,struct task_struct就是用来描述一个线程的,可能是内核线程,也可能是用户空间的线程,linux中的进?#35752;?#30340;是一组task_struct,而这些task_struct共享某些资源。

    以上是我的理解
    justin
    2015-10-22 11:51
    @linuxer:没有想到linuxer回复的这么快,十分?#34892;唬?
    最近我也在做一些linux驱动相关的工作,但是总感觉理解不够深入,后续还希望不吝指教。
    无名客
    2014-03-31 21:08
    好博客,好博文!
    活动板房
    2014-03-31 16:24
    是完全没看懂
    动漫那点事
    2014-03-26 15:09
    来?#32431;矗?#34429;然没看懂

    发表评论:

    Copyright @ 2013-2015 蜗窝科技 All rights reserved. Powered by emlog
    连码三全中是什么
  • <div id="0yoao"><tr id="0yoao"></tr></div>
    <dl id="0yoao"></dl>
  • <sup id="0yoao"></sup>
    <div id="0yoao"><tr id="0yoao"></tr></div>
  • <div id="0yoao"><tr id="0yoao"></tr></div>
  • <div id="0yoao"><tr id="0yoao"></tr></div>
    <dl id="0yoao"></dl>
  • <sup id="0yoao"></sup>
    <div id="0yoao"><tr id="0yoao"></tr></div>
  • <div id="0yoao"><tr id="0yoao"></tr></div>
  • 江西多乐彩分析 nba球队 体彩p5 山西快乐十分钟官网 体育彩票6场半全场 广西快乐双彩票 东方6+1生肖走势图 广西11选5开奖走势图 斗地主下载赢话费 重庆幸运农场走势 吉林快三开将结果 刘伯温平特 139期快乐双彩开奖结果 排列五走势图最近五百 体彩36选7开奖结果查