Chinaunix首页 | 论坛 | 博客
  • 博客访问: 151902
  • 博文数量: 20
  • 博客积分: 1515
  • 博客等级: 上尉
  • 技术积分: 305
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-14 10:06
文章分类

全部博文(20)

文章存档

2011年(2)

2010年(4)

2009年(14)

我的朋友

分类: LINUX

2009-07-02 00:05:47

感觉关于linux系统基础方面的知识越来越模糊。好些东西知道大概是怎么回事。但是要说就说不清楚了。现在再整理一下。

一、进程标识

1)        什么是进程ID

每个进程都会有一个唯一非负整数的ID,就称为进程ID,因为其具有唯一性,常用来做其它标识符的部分以保证唯一性。

2)        特殊的进程ID

l         0  调度进程ID,也称为交换进程,它是内核的一部分。也被称为系统进程

l         1  inid进程,在自举过程结束时由内核调用;i n i t通常读与系统有关的初始化文件( / e t c / r c*文件),并将系统引导到一个状态(例如多用户)

l         2  精灵进程( pagedaemon)。此进程负责支持虚存系统的请页操作。与交换进程一样,页精灵进程也是内核进程。

3)        相关函数

#include

#include

pid_t getpid(void); 返回:调用进程的进程I D

pid_t getppid(void); 返回:调用进程的父进程I D

uid_t getuid(void); 返回:调用进程的实际用户I D

uid_t geteuid(void); 返回:调用进程的有效用户I D

gid_t getgid(void); 返回:调用进程的实际组I D

gid_t getegid(void); 返回:调用进程的有效组I D

l         与一个进程相关联的I D有六个或更多,如下图

l         实际用户I D和实际组I D标识我们究竟是谁。这两个字段在登录时取自口令文件中的登录项。通常,在一个登录会话期间这些值并不改变,但是超级用户进程有方法改变它们.

l         有效用户I D,有效组I D以及添加组I D决定了我们的文件访问权

l         保存的设置-用户- I D和设置-- I D在执行一个程序时包含了有效用户I D和有效组I D的副本

二、fork函数

forklinux内核创建一个新进程的唯一方法,由fork创建的新进程称为子进程。。该函数被调用一次,但返回两次。两次返回的区别是子进程的返回值是0,而父进程的返回值则是新子进程的进程I D

1)        为什么fork要返回两次

l         fork是复制,包括了2个内核页面放进程描述符和其他资源,以及指向核外虚存页面的指针,fork后父子进程内容完全一样,所以需要不同的返回值来区分。当然,现在的fork里还有很多参数,用来控制页拷贝来提高效率。

l         fork将子进程I D返回给父进程的理由是:因为一个进程的子进程可以多于一个,所以没有一个函数使一个进程可以获得其所有子进程的进程I D

l         fork使子进程得到返回值0的理由是:一个进程只会有一个父进程,所以子进程总是可以调用g e t p p i d以获得其父进程的进程I D (进程ID 0总是由交换进程使用,所以一个子进程的进程I D不可能为0 )

2)        子进程会复制和继承父进程哪些数据和资源

l         子进程是父进程的复制品。例如,子进程获得父进程数据空间、堆和栈的复制品。注意,这是子进程所拥有的拷贝。父、子进程并不共享这些存储空间部分。如果正文段是只读的,则父、子进程共享正文段, 现在很多的实现并不做一个父进程数据段和堆的完全拷贝,因为在f o r k之后经常跟随着e x e c。作为替代,使用了在写时复制( C o p y - O n - Write, COW)的技术。

l         f o r k时由父进程打开的描述符都被复制到子进程中

l         其它继承的还有实际用户I D、实际组I D、有效用户I D、有效组I D。添加组I D。进程组I D。对话期I D。控制终端。设置-用户- I D标志和设置-- I D标志

l         信号屏蔽和排列、环境、连接的共享存储段、资源限制

3)        什么情况下会fork失败

l         系统中已经有了太多的进程(通常意味着某个方面出了问题)

l         该实际用户I D的进程总数超过了系统限制。C H I L D _ M A X规定了每个实际用户I D在任一时刻可具有的最大进程数。

三、exit函数

1)        进程有三种正常终止法及两种异常终止法

A.  正常终止: 

l m a i n函数内执行r e t u r n语句。这等效于调用e x i t

l 调用e x i t函数。此函数由ANSI C定义,其操作包括调用各终止处理程序(终止处理程序在调用a t e x i t函数时登录),然后关闭所有标准I / O流等。因为ANSI C并不处理文件描述符、多进程(父、子进程)以及作业控制,所以这一定义对U N I X系统而言是不完整的。

l 调用_ e x i t系统调用函数。此函数由e x i t调用,它处理U N I X特定的细节。

A.  异常终止:

l 调用a b o r t。它产生S I G A B RT信号,所以是下一种异常终止的一种特例。

l 当进程接收到某个信号时。进程本身(例如调用a b o r t函数)、其他进程和内核都能产生传送到某一进程的信号。例如,进程越出其地址空间访问存储单元,或者除以0,内核就会为该进程产生相应的信号。

B.   不管进程如何终止,最后都会执行内核中的同一段代码。这段代码为相应进程关闭所有打开描述符,释放它所使用的存储器等等

2)        什么是坐僵死进程

l       一个已经终止、但是其父进程尚未对其进行善后处理(获取终止子进程的有关信息、释放它仍占用的资源)的进程被称为僵死进程( z o m b i e

四、Waitwaitpid

前面讲了进程各种终止的情况,而且进程终止是一个异步事件,那么作为一个父进程如何获取子进程的终止状态呢?在linux系统中。当一个进程正常或者异常终止时,都会发送一个SIGCHLD信号,父进程可以忽略该信号,或者提供一个该信号发生时即被调用执行的函数(信号处理程序),能够捕捉此信号的函数有: wait waitpid等。下面先简单的介绍这两个函数

1)          函数原型

#include

#include

pid_t wait(int*statloc) ;

pid_t waitpid(pid_t pid,int *statloc,int options) ;

两个函数返回:若成功则为进程I D,若出错则为-1

2)          调用waitwaitpid的进程可能会怎么样?

l         阻塞(如果其所有子进程都还在运行)

l         带子进程的终止状态立即返回(如果一个子进程已终止,正等待父进程存取其终止状态)

l         出错立即返回(如果它没有任何子进程)

3)          waitwaitpid有什么区别

l       在一个子进程终止前, wait 使其调用者阻塞,而waitpid 有一选择项,可使调用者不阻塞。

l       waitpid并不等待第一个终止的子进程—它有若干个选择项,可以控制它所等待的进程。

4)          怎么检查子进程返回的状态

这两个函数都有一个参 int *statloc,如果*statloc不为空。则子进程的返回状态就保存在它所指向的单元内,那么要怎么才能检查出这个状态呢?已经使用以下几个宏来检查(当你不关心子进程的终止状态时,可把*statloc置为了NULL

l         WIFEXITED(status),若为正常终止子进程返回的状态,则为真。对于这种情况可执行WIFEXITED(status),取子进程传送给exit_exit参数的低8

l         WIFSIGNALED(status),若为异常终止子进程返回的状态,则为真(接到一个不捕捉的信号)。对于这种情况,可执行WTERMSIG(status)取使子进程终止的信号编号。

l         WIFSTOPPED(status),若为当前暂停子进程的返回的状态,则为真。对于这种情况,可执行WSTOPSIG(status)取使子进程暂停的信号编号

(未完)

阅读(2435) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

f.u.moon2009-11-23 16:23:06

very good!