分类: LINUX
2008-11-18 21:05:24
今天读了第二章,与大家分享一下我的心得。
1、linux系统中允许同时存在的进程的最大数目为32767,这是因为PID的最大值默认设置为32767(short int短整型的最大值)。如果需要更多进程,系统管理员可以通过修改/proc/sys/kernel/pid_max来提高上限。 2、内核把进程存放在叫做任务队列(task list)的双向循环链表中。链表中的每一项都是类型为task_struct,称为进程描述符的结构,该结构在32位机器上大约有1.7K字节。2.6内核通过slab分配器动态生成task_struct。 3、进程描述符中的state域描述了进程当前的状态,该域的值必为下列五种状态之一: • TASK_RUNNING(运行) — 进程是可执行的;它或者正在执行,或者在运行队列中等待执行。 • TASK_INTERRUPTIBLE(可中断) — 进程正在睡眠(也就是说它被阻塞),等待某些条件的达成。一旦这些条件达成,内核就会把进程状态设置为运行。处于此状态的进程也会因为收到信号而被提前唤醒并投入运行。 • TASK_UNINTERRUPTIBLE(不可中断) — 除了不会因为接收到信号而被唤醒从而投入运行,这个状态与可中断状态相同。这个状态通常在进程必须在等待时不受干扰或等待事件很快发生时出现。 • TASK_ZOMBIE(僵死) — 该进程已经结束了,但是其父进程还没有调用wait4()系统调用。为了父进程能够获知它的消息,子进程的进程描述符仍然被保留着。 • TASK_STOP PED(停止) — 进程停止执行。通常这种状态发生在接收到SIGSTOP、SIGTSTP、SIGTTIN、SIGTTOU等信号的时候。此外,在调试期间接收到任何信号,都会使进程进入这种状态。 4、系统调用和异常处理程序是对内核明确定义的接口。进程只有通过这些接口才能陷入内核执行。Linux中所有的进程都是PID为1的init进程的后代。 5、fork()通过拷贝当前进程创建一个子进程。Linux的fork()使用写时拷贝(copy-on-write)页实现。写时拷贝是一种可以推迟 甚至免除拷贝数据的技术。内核此时并不复制整个进程地址空间,而是让父进程和子进程共享同一个拷贝。也就是说,资源的复制只有在需要写入的时候才进行,在 此之前,只是以只读方式共享。 6、vfork()系统调用和fork()的功能相同,除了不拷贝父进程的页表项。子进程作为父进程的一个单独的线程在它的地址空间里运行,父进程被阻塞,直到子进程退出或执行exec()。子进程不能向地址空间写入。但由于其设计并不优良所以最好让它逐渐淡出。 7、Linux通过clone()系统调用实现fork()。这个调用通过一系列参数标志来指明父、子进程需要共享的资源。如一个普通的fork()的实 现是clone(SIGCHLD,0); vfork()是clone(CLONE_VFORK | CLONE_VM | SIGCHLD,0); clone()的参数标志定义如下: • CLONE_CLEARTID — 清除TID • CLONE_DETACHED — 父进程不需要子进程退出时发送SIGCHLD • CLONE_FILES — 父子进程共享打开的文件 • CLONE_FS — 父子进程共享文件系统信息 • CLONE_IDLETASK — 将PID设置为0(只供idle进程使用) • CLONE_NEWNS — 为子进程创建新的命名空间 • CLONE_PARENT — 指定子进程与父进程拥有同一个父进程 • CLONE_PTRACE — 继续调试子进程 • CLONE_SETTID — 将TID回写至用户空间 • CLONE_SETTLS — 为子进程创建新的TLS • CLONE_SIGHAND — 父子进程共享信号处理函数 • CLONE_SYSVSEM — 父子进程共享System V SEM_UNDO语义 • CLONE_THREAD — 父子进程放入相同的线程组 • CLONE_VFORK — 调用vfork(),所以父进程准备睡眠等待子进程将其唤醒 • CLONE_VM — 父子进程共享地址空间 • CLONE_KERNEL — 定义了内核线程常用到的参数标志:CLONE_FS、CLONE_FILES、CLONE_SIGHAND。 |