日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

Linux中的进程组及会话

發(fā)布時(shí)間:2024/4/18 linux 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux中的进程组及会话 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

將闡述Linux內(nèi)核中的如下幾個(gè)概念?
1) 進(jìn)程組?
2) 會(huì)話?
3) 控制終端?
前面的概念來(lái)源于前人,我只是站在前人的肩膀上結(jié)合內(nèi)核中的實(shí)現(xiàn)加深概念理解。?

1.概念:?

a)進(jìn)程組?
Shell 上的一條命令行形成一個(gè)進(jìn)程組?
每個(gè)進(jìn)程屬于一個(gè)進(jìn)程組?
每個(gè)進(jìn)程組有一個(gè)領(lǐng)頭進(jìn)程?
進(jìn)程組的生命周期到組中最后一個(gè)進(jìn)程終止, 或加入其他進(jìn)程組為止?
getpgrp: 獲得進(jìn)程組 id, 即領(lǐng)頭進(jìn)程的 pid?
setpgid: 加入進(jìn)程組和建立新的進(jìn)程組?
前臺(tái)進(jìn)程組和后臺(tái)進(jìn)程組?

===============================================================================?
#include <unistd.h>?

int setpgid (pid_t pid, pid_t pgid);?
pid_t getpgid (pid_t pid);?
int setpgrp (void);?
pid_t getpgrp (void);?
-------------------------------------------------------------------------------?
進(jìn)程只能將自身和其子進(jìn)程設(shè)置為進(jìn)程組 id.?
某個(gè)子進(jìn)程調(diào)用 exec 函數(shù)之后, 就不能再將該子進(jìn)程的 id 作為進(jìn)程組 id.?
===============================================================================?

b)會(huì)話?
一次登錄形成一個(gè)會(huì)話?
一個(gè)會(huì)話可包含多個(gè)進(jìn)程組, 但只能有一個(gè)前臺(tái)進(jìn)程組.?
setsid 可建立一個(gè)新的會(huì)話?
===============================================================================?
#include <unistd.h>?

pid_t setsid(void);?
-------------------------------------------------------------------------------?
如果調(diào)用進(jìn)程不是進(jìn)程組的領(lǐng)頭進(jìn)程, 該函數(shù)才能建立新的會(huì)話.?
調(diào)用 setsid 之后, 進(jìn)程成為新會(huì)話的領(lǐng)頭進(jìn)程.?
進(jìn)程成為新進(jìn)程組的領(lǐng)頭進(jìn)程.?
進(jìn)程失去控制終端?
===============================================================================?

c)控制終端?
會(huì)話的領(lǐng)頭進(jìn)程打開(kāi)一個(gè)終端之后, 該終端就成為該會(huì)話的控制終端 (SVR4/Linux)?
與控制終端建立連接的會(huì)話領(lǐng)頭進(jìn)程稱為控制進(jìn)程 (session leader)?
一個(gè)會(huì)話只能有一個(gè)控制終端?
產(chǎn)生在控制終端上的輸入和信號(hào)將發(fā)送給會(huì)話的前臺(tái)進(jìn)程組中的所有進(jìn)程?
終端上的連接斷開(kāi)時(shí) (比如網(wǎng)絡(luò)斷開(kāi)或 Modem 斷開(kāi)), 掛起信號(hào)將發(fā)送到控制進(jìn)程(session leader)?

2. Linux中的實(shí)現(xiàn)舉例,用以驗(yàn)證上述規(guī)則:?

asmlinkage long sys_getpgid(pid_t pid)?
{?
if (!pid) {?
return current->pgrp;?
} else {?
int retval;?
struct task_struct *p;?

read_lock(&tasklist_lock);?
p = find_task_by_pid(pid);?

retval = -ESRCH;?
if (p)?
retval = p->pgrp;?
read_unlock(&tasklist_lock);?
return retval;?
}?
}?

/*?
* This needs some heavy checking ...?
* I just haven't the stomach for it. I also don't fully?
* understand sessions/pgrp etc. Let somebody who does explain it.?
*?
* OK, I think I have the protection semantics right.... this is really?
* only important on a multi-user system anyway, to make sure one user?
* can't send a signal to a process owned by another. -TYT, 12/12/91?
*?
* Auch. Had to add the 'did_exec' flag to conform completely to POSIX.?
* LBT 04.03.94?
*/?

asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)?
{?
struct task_struct * p;?
int err = -EINVAL;?

if (!pid)?
pid = current->pid;?
if (!pgid)?
pgid = pid;?
if (pgid < 0)?
return -EINVAL;?

/* From this point forward we keep holding onto the tasklist lock?
* so that our parent does not change from under us. -DaveM?
*/?
read_lock(&tasklist_lock);?

/*第一前提: 先要驗(yàn)證要設(shè)定的進(jìn)程是否存在,不存在的話不能做事*/?
err = -ESRCH;?
p = find_task_by_pid(pid);?
if (!p)?
goto out;?

/* 第二前提: 先要檢查做這個(gè)操作的權(quán)限:?
當(dāng)前進(jìn)程只能將自身和其子進(jìn)程設(shè)置為進(jìn)程組id,并且?
當(dāng)前進(jìn)程和其子進(jìn)程必須屬于同一次會(huì)話?
(同組的進(jìn)程一定屬于同一次會(huì)話)?
*/?
if (p->p_pptr == current || p->p_opptr == current)?
{?
err = -EPERM;?

/*如果不屬于同一次會(huì)話(同一次控制臺(tái)),不可以*/?
if (p->session != current->session)?
goto out;?
err = -EACCES;?

/*某個(gè)子進(jìn)程調(diào)用 exec 函數(shù)之后, 就不能再將該子進(jìn)程的 id 作為進(jìn)程組 id*/?
if (p->did_exec)?
goto out;?
}?
else if (p != current)?
goto out;?

err = -EPERM;?

/*boolean value for session group leader */?
/*如果是一次會(huì)話的leader,也不可以?
注意進(jìn)程組的首領(lǐng)進(jìn)程也是可以改變組id的*/?
if (p->leader)?
goto out;?

/*好!幾個(gè)前提條件全滿足了,要做正事了:?
但是是不是組號(hào)的合法性還沒(méi)有驗(yàn)證?見(jiàn)后話!*/?

/*要設(shè)進(jìn)程號(hào)不是要設(shè)定的組號(hào),如果是,直接設(shè),因?yàn)檫@?
意味著是增加了以自己的pid作為新的組號(hào)的進(jìn)程組,這個(gè)?
進(jìn)程也將成為新進(jìn)程組的首領(lǐng)進(jìn)程,所以在此根本不用比較?
會(huì)話號(hào),自己對(duì)自己肯定是同一次會(huì)話.如果條件不滿足,則?
要做這些判斷*/?
if (pgid != pid)?
{?
struct task_struct * tmp;?
for_each_task (tmp)?
{?
/*能不能找到一個(gè)進(jìn)程,組號(hào)正好是要設(shè)定的組號(hào),?
并且和要設(shè)定的進(jìn)程屬于同一個(gè)控制臺(tái)(同一個(gè)會(huì)話)?
找到才可以設(shè)定,其實(shí)這里就是要判定組號(hào)的合法性,?
即必須是一個(gè)已經(jīng)存在的組,而且和當(dāng)前同一次會(huì)話才?
可以操作,這個(gè)也不能忘記,其實(shí)就是說(shuō):同組的進(jìn)程?
一定屬于同一次會(huì)話*/?
if (tmp->pgrp == pgid &&?
tmp->session == current->session)?
goto ok_pgid;?
}?

goto out;?
}?

ok_pgid:?
p->pgrp = pgid;?
err = 0;?
out:?
/* All paths lead to here, thus we are safe. -DaveM */?
read_unlock(&tasklist_lock);?
return err;?
}?

asmlinkage long sys_getsid(pid_t pid)?
{?
if (!pid) {?
return current->session;?
} else {?
int retval;?
struct task_struct *p;?

read_lock(&tasklist_lock);?
p = find_task_by_pid(pid);?

retval = -ESRCH;?
if(p)?
retval = p->session;?
read_unlock(&tasklist_lock);?
return retval;?
}?
}?

asmlinkage long sys_setsid(void)?
{?
struct task_struct * p;?
int err = -EPERM;?

read_lock(&tasklist_lock);?
for_each_task(p)?
{?
/*如果當(dāng)前進(jìn)程是一個(gè)進(jìn)程組的首領(lǐng)進(jìn)程,?
則不能建立一個(gè)新的會(huì)話*/?
if (p->pgrp == current->pid)?
goto out;?
}?

/*將新創(chuàng)建會(huì)話的leader設(shè)定為創(chuàng)建者就是當(dāng)前進(jìn)程*/?
current->leader = 1;?

/*清楚看見(jiàn)一個(gè)新的進(jìn)程組誕生了?
當(dāng)前進(jìn)程成為新進(jìn)程組的首領(lǐng)進(jìn)程?
新會(huì)話的id 是當(dāng)前進(jìn)程號(hào),也是新會(huì)話的leader?
*/?
current->session = current->pgrp = current->pid;?

/*當(dāng)前進(jìn)程失去控制終端*/?
current->tty = NULL;?
current->tty_old_pgrp = 0;?
err = current->pgrp;?
out:?
read_unlock(&tasklist_lock);?
return err;?

}

總結(jié)

以上是生活随笔為你收集整理的Linux中的进程组及会话的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。