- 浏览: 664588 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
sztime:
可以在文本框上绑定事件来禁用回车键, 我就是这样做的.在IE中 ...
form 回车自动提交问题 -
damoqiongqiu:
非常好的文章,很透彻不过有一句话小僧腆着脸补充一下:“1111 ...
为什么要用补码来做存储 -
wuyizhong:
原来如此啊。
form 回车自动提交问题 -
luliangy:
谢楼主~!
用C语言扩展Python的功能 -
kwong:
很有用,谢谢
火狐和IE 对css 样式解释的差异
将阐述Linux内核中的如下几个概念
1) 进程组
2) 会话
3) 控制终端
前面的概念来源于前人,我只是站在前人的肩膀上结合内核中的实现加深概念理解。
1.概念:
a)进程组
Shell 上的一条命令行形成一个进程组
每个进程属于一个进程组
每个进程组有一个领头进程
进程组的生命周期到组中最后一个进程终止, 或加入其他进程组为止
getpgrp: 获得进程组 id, 即领头进程的 pid
setpgid: 加入进程组和建立新的进程组
前台进程组和后台进程组
===============================================================================
#include <unistd.h>
int setpgid (pid_t pid, pid_t pgid);
pid_t getpgid (pid_t pid);
int setpgrp (void);
pid_t getpgrp (void);
-------------------------------------------------------------------------------
进程只能将自身和其子进程设置为进程组 id.
某个子进程调用 exec 函数之后, 就不能再将该子进程的 id 作为进程组 id.
===============================================================================
b)会话
一次登录形成一个会话
一个会话可包含多个进程组, 但只能有一个前台进程组.
setsid 可建立一个新的会话
===============================================================================
#include <unistd.h>
pid_t setsid(void);
-------------------------------------------------------------------------------
如果调用进程不是进程组的领头进程, 该函数才能建立新的会话.
调用 setsid 之后, 进程成为新会话的领头进程.
进程成为新进程组的领头进程.
进程失去控制终端
===============================================================================
c)控制终端
会话的领头进程打开一个终端之后, 该终端就成为该会话的控制终端 (SVR4/Linux)
与控制终端建立连接的会话领头进程称为控制进程 (session leader)
一个会话只能有一个控制终端
产生在控制终端上的输入和信号将发送给会话的前台进程组中的所有进程
终端上的连接断开时 (比如网络断开或 Modem 断开), 挂起信号将发送到控制进程(session leader)
2. Linux中的实现举例,用以验证上述规则:
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);
/*第一前提: 先要验证要设定的进程是否存在,不存在的话不能做事*/
err = -ESRCH;
p = find_task_by_pid(pid);
if (!p)
goto out;
/* 第二前提: 先要检查做这个操作的权限:
当前进程只能将自身和其子进程设置为进程组id,并且
当前进程和其子进程必须属于同一次会话
(同组的进程一定属于同一次会话)
*/
if (p->p_pptr == current || p->p_opptr == current)
{
err = -EPERM;
/*如果不属于同一次会话(同一次控制台),不可以*/
if (p->session != current->session)
goto out;
err = -EACCES;
/*某个子进程调用 exec 函数之后, 就不能再将该子进程的 id 作为进程组 id*/
if (p->did_exec)
goto out;
}
else if (p != current)
goto out;
err = -EPERM;
/*boolean value for session group leader */
/*如果是一次会话的leader,也不可以
注意进程组的首领进程也是可以改变组id的*/
if (p->leader)
goto out;
/*好!几个前提条件全满足了,要做正事了:
但是是不是组号的合法性还没有验证?见后话!*/
/*要设进程号不是要设定的组号,如果是,直接设,因为这
意味着是增加了以自己的pid作为新的组号的进程组,这个
进程也将成为新进程组的首领进程,所以在此根本不用比较
会话号,自己对自己肯定是同一次会话.如果条件不满足,则
要做这些判断*/
if (pgid != pid)
{
struct task_struct * tmp;
for_each_task (tmp)
{
/*能不能找到一个进程,组号正好是要设定的组号,
并且和要设定的进程属于同一个控制台(同一个会话)
找到才可以设定,其实这里就是要判定组号的合法性,
即必须是一个已经存在的组,而且和当前同一次会话才
可以操作,这个也不能忘记,其实就是说:同组的进程
一定属于同一次会话*/
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)
{
/*如果当前进程是一个进程组的首领进程,
则不能建立一个新的会话*/
if (p->pgrp == current->pid)
goto out;
}
/*将新创建会话的leader设定为创建者就是当前进程*/
current->leader = 1;
/*清楚看见一个新的进程组诞生了
当前进程成为新进程组的首领进程
新会话的id 是当前进程号,也是新会话的leader
*/
current->session = current->pgrp = current->pid;
/*当前进程失去控制终端*/
current->tty = NULL;
current->tty_old_pgrp = 0;
err = current->pgrp;
out:
read_unlock(&tasklist_lock);
return err;
}
发表评论
-
信号表
2010-09-02 00:59 559SIGHUP 终止进程 终端线路挂断 SI ... -
Mogile安装实践
2008-09-01 22:05 2127Mogile安装实践 Filed under: Mog ... -
ld.so.conf 文档和PKG_CONFIG_PATH变量
2008-08-30 02:37 2303一、编译和连接 ... -
gcc 安装
2008-08-25 02:26 3503关于GCC的升级,一定要用rpm包吗? 參考:::2004年 ... -
g++下 hash_map
2008-08-25 01:33 3378一个hash_map使用错误 g++ ... -
stdport 安装
2008-08-25 01:27 968stlport安装使用手记 段 ... -
linux下rpc应用 例程详解
2008-07-17 15:51 3142关于“RPC语言” RPC语言也是一种专门的编程语言,当然这 ... -
Linux下编写动态链接库的简单过程
2008-07-10 01:12 3081(1) 使用编译选项 -fPIC ,产生与位置无关 ... -
rsync中文手册
2007-08-31 00:55 925用rsync实现网站镜像和 ... -
管理幽默:三个囚犯的选择
2007-10-13 20:13 715有一个美国人、一个法国人和一个犹太人要被关进监狱3年。监狱长让 ... -
linux下批量替换一个目录下的文件某个字符串
2007-12-28 01:19 1078太酷了!! sed -i "s/oldstring/ ... -
linux下编程学习--- 静态库和动态库的编译
2008-02-03 16:28 2231学习linux下c很长一段对动态库和静态库的编译和使用总是 ... -
linux下编程学习----- 线程同步之无名信号量
2008-02-04 14:49 2160这是一个书上的例子,逻辑是:一个线程生产一组数字1、2、3. ... -
linux下编程学习----- 远程过程调用(rpc)
2008-02-19 18:14 6580一、概述 在传统的编程概念中,过程是由程序员在本地 ... -
linux学习之-- 性能分析
2008-02-22 18:57 1210http://hi.baidu.com/chegaoying/ ... -
linux性能分析 -- top
2008-02-22 19:36 10031top top命令是最流行的性能工具之一。大多数系统管理员运行 ... -
linux性能分析 -- sar
2008-02-22 19:37 14421sarsar是一个优秀的一般性能监视工具,它可以输出Linux ... -
linux性能分析 -- vmstat
2008-02-22 19:38 3516vmstatvmstat命令也是显示Linux性能指标的方法, ... -
linux性能分析 -- iostat
2008-02-22 19:39 3741iostatiostat命令是另一个 ... -
linux性能分析 -- free
2008-02-22 19:40 867free free命令输出内存和交换信息,与top命令的作用非 ...
相关推荐
在这个过程中,你可能需要了解一些关键概念,如系统调用、中断处理、进程调度等,这些都是Linux内核的基础。同时,理解内核模块、驱动程序和文件系统的运作机制也是必不可少的。 总之,Linux内核调试是一个复杂但...
Linux内核进程管理是一个复杂的主题,涉及对进程的创建、调度和回收等一系列操作。其中,进程ID(PID)作为进程的唯一标识,起着至关重要的作用。在Linux操作系统中,每个进程都有一个唯一的PID,它用于区分系统中的...
10. **`start_kernel`函数**:这是Linux内核启动的核心部分,它负责启动内核服务、初始化子系统,如进程管理、虚拟文件系统、网络堆栈等。`start_kernel`会调用一系列的初始化函数,如`init/main.c`中的`do_basic_...
总的来说,搭建Linux内核调试环境是一项技术性很强的工作,但通过VMware和kgdb的结合,可以极大地简化这一过程。熟练掌握这些技能,不仅能够提高你的问题解决能力,还能让你更深入地理解Linux内核的工作原理。
Linux内核对进程个数有一定的限制,但在2.4及更高版本中,这个限制更多地取决于可用的物理内存。每个进程的PCB和系统堆栈占用约8KB空间,因此总的进程数量受到物理内存的一半大小限制。 总的来说,Linux内核结构与...
标题中的“cpp-从Linux内核密钥中提取Kerberos票证的工具”表明这是一个用C++编写的程序,其主要功能是读取Linux内核中的密钥,并用于解析和提取Kerberos票证。Kerberos是一种广泛使用的网络身份验证协议,它通过...
Linux内核调试是一个复杂但至关重要的任务,尤其对于开发者来说,理解内核的运行机制和查找潜在问题至关重要。本文将详细介绍如何使用特定工具,如OpenJTAG、Eclipse和OpenOCD来调试Linux内核。 首先,我们从通过U-...
在这个主题中,我们将重点关注Linux内核如何管理和调度进程,以及内核的基本架构。 一、Linux内核结构 1. **模块化设计**:Linux内核采用模块化设计,使得内核可以根据实际需求进行裁剪,只加载必要的驱动和服务,...
在Linux系统中,这个模型主要遵循OSI七层模型或TCP/IP四层模型(在Linux内核中更常被引用)。接收包的相关数据结构和处理过程则是理解网络通信的关键,它们涉及到如何接收、解析和处理网络中的数据包。TCP/IP协议族...
在Linux内核模式下,PPPoE客户端的实现可以分为两个阶段:地址发现阶段和会话阶段。在地址发现阶段,主机需要执行Discovery来确定对方的以太网MAC地址,并建立起一个PPPoE会话标识符SESSION-ID。在会话阶段,主机和...
《Linux网络体系结构:Linux内核中网络协议的设计与实现》是深入理解Linux网络操作系统的经典之作,尤其对于网络协议栈的实现有详尽的解析。本书主要关注于Linux内核如何处理网络通信,涵盖了从数据链路层到应用层的...
在Android开发过程中,有时需要对Linux内核进行定制和优化,以满足特定设备或功能的需求。为此,开发者通常会在虚拟机上搭建一个Linux开发环境,然后通过远程终端工具如secureCRT进行连接。以下是一个详细的Android ...
- 在内核中触发DDB调试会话,允许在运行过程中进行调试操作。 #### 十五、使用GDB调试运行中的系统 - 通过网络连接远程主机,使用GDB进行调试。 #### 十六、内核调试选项 - **`INVARIANTS`**:用于检查内核中的...
在写作过程中,作者们不断地更新内容,根据Linux内核的发展动态进行调整。例如,书中原始的源代码取自Linux内核的2.3.38版本,后续又根据2.3.98、2.4.0测试版进行更新,最终定稿于2.4.0正式版。作者指出,尽管当读者...