久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      一起分析Linux經(jīng)典技巧之進程ID號

      本篇文章給大家?guī)砹薼inux中進程ID號分析的相關(guān)知識,Linux進程總是會分配一個號碼用于在其命名空間中唯一地標識它們。該號碼被稱作進程ID號,簡稱PID,下面就一起來看一下相關(guān)問題,希望對大家有幫助。

      一起分析Linux經(jīng)典技巧之進程ID號

      ??本文中的代碼摘自 Linux內(nèi)核5.15.13版本。

      ??Linux進程總是會分配一個號碼用于在其命名空間中唯一地標識它們。該號碼被稱作進程ID號,簡稱PID。用fork或clone產(chǎn)生的每個進程都由內(nèi)核自動地分配了一個新的唯一的PID值。

      一、進程ID

      1.1、其他ID

      ??每個進程除了PID這個特征值之外,還有其他的ID。有下列幾種可能的類型

      ??1、 處于某個線程組(在一個進程中,以標志CLONE_THREAD來調(diào)用clone建立的該進程的不同的執(zhí)行上下文,我們在后文會看到)中的所有進程都有統(tǒng)一的線程組ID( TGID)。如果進程沒有使用線程,則其PID和TGID相同。線程組中的主進程被稱作組長( group leader)。通過clone創(chuàng)建的所有線程的task_struct的group_leader成員,會指向組長的task_struct實例。

      ??2、另外,獨立進程可以合并成進程組(使用setpgrp系統(tǒng)調(diào)用)。進程組成員的task_struct的pgrp屬性值都是相同的,即進程組組長的PID。進程組簡化了向組的所有成員發(fā)送信號的操作,這對于各種系統(tǒng)程序設(shè)計應(yīng)用(參見系統(tǒng)程序設(shè)計方面的文獻,例如[ SR05])是有用的。請注意,用管道連接的進程包含在同一個進程組中。

      ??3、 幾個進程組可以合并成一個會話。會話中的所有進程都有同樣的會話ID,保存在task_struct的session成員中。 SID可以使用setsid系統(tǒng)調(diào)用設(shè)置。它可以用于終端程序設(shè)計。

      1.2、全局ID和局部ID

      ??名空間增加了PID管理的復(fù)雜性。 PID命名空間按層次組織。在建立一個新的命名空間時,該命名空間中的所有PID對父命名空間都是可見的,但子命名空間無法看到父命名空間的PID。但這意味著某些進程具有多個PID,凡可以看到該進程的命名空間,都會為其分配一個PID。 這必須反映在數(shù)據(jù)結(jié)構(gòu)中。我們必須區(qū)分局部ID和全局ID。

      ??1、 全局ID是在內(nèi)核本身和初始命名空間中的唯一ID號,在系統(tǒng)啟動期間開始的init進程即屬于初始命名空間。對每個ID類型,都有一個給定的全局ID,保證在整個系統(tǒng)中是唯一的。

      ??2、 局部ID屬于某個特定的命名空間,不具備全局有效性。對每個ID類型,它們在所屬的命名空間內(nèi)部有效,但類型相同、值也相同的ID可能出現(xiàn)在不同的命名空間中。

      1.3、ID實現(xiàn)

      ??全局PID和TGID直接保存在task_struct中,分別是task_struct的pid和tgid成員,在sched.h文件里:

      struct task_struct {...pid_t pid;pid_t tgid;...}

      ??這兩項都是pid_t類型,該類型定義為__kernel_pid_t,后者由各個體系結(jié)構(gòu)分別定義。通常定義為int,即可以同時使用232個不同的ID。

      二、管理PID

      ??一個小型的子系統(tǒng)稱之為PID分配器( pid allocator)用于加速新ID的分配。此外,內(nèi)核需要提供輔助函數(shù),以實現(xiàn)通過ID及其類型查找進程的task_struct的功能,以及將ID的內(nèi)核表示形式和用戶空間可見的數(shù)值進行轉(zhuǎn)換的功能。

      2.1、PID命名空間的表示方式

      ??在pid_namespace.h文件內(nèi)有如下定義:

      struct pid_namespace { 	struct idr idr; 	struct rcu_head rcu; 	unsigned int pid_allocated; 	struct task_struct *child_reaper; 	struct kmem_cache *pid_cachep; 	unsigned int level; 	struct pid_namespace *parent;#ifdef CONFIG_BSD_PROCESS_ACCT 	struct fs_pin *bacct;#endif 	struct user_namespace *user_ns; 	struct ucounts *ucounts; 	int reboot;	/* group exit code if this pidns was rebooted */ 	struct ns_common ns;} __randomize_layout;

      ??每個PID命名空間都具有一個進程,其發(fā)揮的作用相當(dāng)于全局的init進程。 init的一個目的是對孤兒進程調(diào)用wait4,命名空間局部的init變體也必須完成該工作。 child_reaper保存了指向該進程的task_struct的指針。

      ??parent是指向父命名空間的指針, level表示當(dāng)前命名空間在命名空間層次結(jié)構(gòu)中的深度。初始命名空間的level為0,該命名空間的子空間level為1,下一層的子空間level為2,依次遞推。level的計算比較重要,因為level較高的命名空間中的ID,對level較低的命名空間來說是可見的。從給定的level設(shè)置,內(nèi)核即可推斷進程會關(guān)聯(lián)到多少個ID。

      2.2、PID的管理

      2.2.1、PID的數(shù)據(jù)結(jié)構(gòu)

      ??PID的管理圍繞兩個數(shù)據(jù)結(jié)構(gòu)展開: struct pid是內(nèi)核對PID的內(nèi)部表示,而struct upid則表示特定的命名空間中可見的信息。兩個結(jié)構(gòu)的定義在文件pid.h內(nèi),分別如下:

      /*  * What is struct pid?  *  * A struct pid is the kernel's internal notion of a process identifier.  * It refers to inpidual tasks, process groups, and sessions.  While  * there are processes attached to it the struct pid lives in a hash  * table, so it and then the processes that it refers to can be found  * quickly from the numeric pid value.  The attached processes may be  * quickly accessed by following pointers from struct pid.  *  * Storing pid_t values in the kernel and referring to them later has a  * problem.  The process originally with that pid may have exited and the  * pid allocator wrapped, and another process could have come along  * and been assigned that pid.  *  * Referring to user space processes by holding a reference to struct  * task_struct has a problem.  When the user space process exits  * the now useless task_struct is still kept.  A task_struct plus a  * stack consumes around 10K of low kernel memory.  More precisely  * this is THREAD_SIZE + sizeof(struct task_struct).  By comparison  * a struct pid is about 64 bytes.  *  * Holding a reference to struct pid solves both of these problems.  * It is small so holding a reference does not consume a lot of  * resources, and since a new struct pid is allocated when the numeric pid  * value is reused (when pids wrap around) we don't mistakenly refer to new  * processes.  *//*  * struct upid is used to get the id of the struct pid, as it is  * seen in particular namespace. Later the struct pid is found with  * find_pid_ns() using the int nr and struct pid_namespace *ns.  */struct upid { 	int nr; 	struct pid_namespace *ns;};struct pid{ 	refcount_t count; 	unsigned int level; 	spinlock_t lock; 	/* lists of tasks that use this pid */ 	struct hlist_head tasks[PIDTYPE_MAX]; 	struct hlist_head inodes; 	/* wait queue for pidfd notifications */ 	wait_queue_head_t wait_pidfd; 	struct rcu_head rcu; 	struct upid numbers[1];};

      ??對于struct upid, nr表示ID的數(shù)值, ns是指向該ID所屬的命名空間的指針。所有的upid實例都保存在一個散列表中。 pid_chain用內(nèi)核的標準方法實現(xiàn)了散列溢出鏈表。struct pid的定義首先是一個引用計數(shù)器count。 tasks是一個數(shù)組,每個數(shù)組項都是一個散列表頭,對應(yīng)于一個ID類型。這樣做是必要的,因為一個ID可能用于幾個進程。所有共享同一給定ID的task_struct實例,都通過該列表連接起來。 PIDTYPE_MAX表示ID類型的數(shù)目:

      enum pid_type{ 	PIDTYPE_PID, 	PIDTYPE_TGID, 	PIDTYPE_PGID, 	PIDTYPE_SID, 	PIDTYPE_MAX,};

      2.2.2、PID與進程的聯(lián)系

      ??一個進程可能在多個命名空間中可見,而其在各個命名空間中的局部ID各不相同。 level表示可以看到該進程的命名空間的數(shù)目(換言之,即包含該進程的命名空間在命名空間層次結(jié)構(gòu)中的深度),而numbers是一個upid實例的數(shù)組,每個數(shù)組項都對應(yīng)于一個命名空間。注意該數(shù)組形式上只有一個數(shù)組項,如果一個進程只包含在全局命名空間中,那么確實如此。由于該數(shù)組位于結(jié)構(gòu)的末尾,因此只要分配

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號