全部博文(842)
分类: LINUX
2012-05-17 15:29:22
进程存在于系统的内存之中,是操作系统可感知、可控制的动态实体。每个进程分为内核态(特权级0)和用户态(特权级3)两种级别。
25. Linux进程的四要素
PCB中的重要信息
进程优先级,priority的值给出进程每次获取CPU后,可使用的时间(按jiffies计)。优先级可通过系统调用sys_setpriority()改变(kernel/sys.c)
rt_priority给出实时进程的优先级,rt_priority+1000给出进程每次获取CPU后,可使用的时间(同样按jiffies计)。实时进程的优先级可通过系统调用sys_sched_setscheduler()改变,不过实际的工作是由setscheduler()完成的,这两个函数均定义在kernel/sched.c中。
Counter:在轮转法(round robin)调度时表示进程当前还可运行多久。在进程开始运行时被赋为priority的值,以后每隔一个tick(时钟中断)递减1,减到0时引起新一轮调度。重新调度将从run-queue队列选出counter值最大的就绪进程获得CPU,因此counter起到了进程的动态优先级的作用(priority则是静态优先级)。
Policy:该进程的进程调度策略,可以通过系统调用sys_sched_setscheduler()更改(kernel/sched.c)。调度策略有:
进程队列指针struct task_struct *next_task, *prev_task;
所有进程(以PCB的形式)组成一个双向链表。next_task和prev_task就是链表的前后向指针。链表的头和尾都是init_task(即0号进程)。通过宏for_each_task 可以很方便的搜索所有进程:
#define for_each_task(p) \
进程队列指针struct task_struct *p_opptr, *p_pptr;
struct task_struct *p_cptr, *p_ysptr, *p_osptr;
以上分别是指向原始父进程(original parent)、父进程(parent)、子进程(youngest child)及新老兄弟进程(younger sibling, older sibling)的指针。相关的操作宏参见kernel/linux/sched.h。
进程约束
Linux系统的进程通信
Linux系统提供了多种通信机制,包括
信号是Unix系统中的最古老的进程间通信方式。它们用来向一个或多个进程发送异步事件信号。信号可以从键盘中断中产生,另外进程对虚拟内存的非法存取等系统错误环境下也会有信号产生。信号还被shell程序用来向其子进程发送任务控制命令。为区别于硬件中断,又称为软中断。使用kill命令(kill -l)可以列出系统中所有已经定义的信号。
Linux 2.2版以后将信号分为两类:
信号处理
信号的接收
Linux通过存储在进程task_struct中的信息来实现信号。信号个数受到处理器字长的限制。32位字长的处理器最多可以有32个信号而64位处理器如Alpha AXP可以有最多64个信号。当前未处理的信号保存在signal域中,并带有保存在blocked中的被阻塞信号的屏蔽码。除了SIGSTOP和SIGKILL外,所有的信号都能被阻塞。
并不是系统中每个进程都可以向所有其它进程发送信号:只有核心和超级用户具有此权限。普通进程只能向具有相同uid和gid的进程或者在同一进程组中的进程发送信号。信号是通过设置task_struct结构中signal域里的某一位来产生的
信号并非一产生就立刻交给进程,而是必须等待到进程再次运行时才交给进程。每次进程从系统调用中退出前,它都会检查signal和blocked域,看是否有可以立刻发送的非阻塞信号。这看起来非常不可靠,但是系统中每个进程都在不停地进行系统调用,如向终端输出字符。当然进程可以选择去等待信号,此时进程将一直处于可中断状态直到信号出现。对当前不可阻塞信号的处理代码放置在sigaction结构中。
Linux是POSIX兼容的,所以当某个特定信号处理例程被调用时,进程可以设定哪个信号可以阻塞。这意味着可以在进程信号处理过程中改变blocked屏蔽码。当信号处理例程结束时,此blocked屏蔽码必须设置成原有值。 因此,Linux添加了一个过程调用来进行整理工作,通过它来重新设置被发送信号进程调用栈中的原有blocked屏蔽码。 对于同一时刻几个信号处理过程,Linux通过堆栈方式来优化其使用,每当一个处理过程退出时,下一个处理过程必须等到整理例程结束后才执行。
套接字是用来实现网络通信的机制。它可以实现数据的双向规模传递,是整个网络通信的基础。
26. 管道的实现
在Linux中,管道通过指向同一个临时VFS inode的两个file数据结构来实现,此VFS inode指向内存中的一个物理页面
无名管道:ls|wc 只存在于内存中 由pipes()创建 只限于有家族关系的进程之间
有名管道:和无名管道功能相同,只是不是内存文件,而是永久性的文件,外存文件。ls -l列出的p文件。有mknod创建(或mkfifo命令)管道文件。由两个进程调用open同时打开一个管道文件,然后分别调用read,write。任何两个进程之间都可以。
27. SYSTEM Ⅴ进程间通信
Undo标志
共享内存允许若干进程共享主存中的某一个区域,且使该区域出现在多个进程的虚地址空间中。
每个新创建的共享内存区域由一个shmid_ds数据结构来表示。该数据结构包含:
28 死锁
29. 进程调度
30.线程
31.在Linux中,每一个用户都可以访问4 GB线性虚拟内存空间。其中,0~3 GB是用户空间,用户可以直接对它进行访问;3~4 GB是内核空间,存放内核访问的代码和数据,用户态的程序不能访问。所有进程的3~4 GB虚拟空间都是一样的,有同样的页目录项,同样的页表, 对应到同样的物理内存段。
32. 对vm-area-struct数据结构的搜寻速度决定了处理缺页中断的效率,而所有vm-area-struct结构是通过一种AVL(Adelson-Velskii and Landis) 树结构连在一起的。如果无法找到vm-area-struct与此失效虚拟地址的对应关系,则系统认为此进程访问了非法虚拟地址。 这时Linux将向进程发送SIGSEGV信号
虚拟段的组织:
v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
Normal
0
7.8 磅
0
2
false
false
false
EN-US
ZH-CN
X-NONE
MicrosoftInternetExplorer4
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:普通表格;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-qformat:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.5pt;
mso-bidi-font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-font-kerning:1.0pt;}