免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 789 | 回复: 0
打印 上一主题 下一主题

Chap3 进程管理 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-29 13:03 |只看该作者 |倒序浏览
  
3.1 进程描述符及任务结构
进程存放在任务队列task list的双向循环链表中;
链表中存放进程描述符,task_struct(定义在)
linux通过slab分配器分配task_struct结构,达到对象复用和缓存着色的目的;
slab分配器动态生成task_struct,只需在栈底船舰一个新的结构struct thread_info:

    struct thread_info {
        struct task_struct *task;
        struct exec_domain *exec_domain;
        unsigned long flags;
        unsigned long status;
        __u32 cpu;
        __s32 preempt_count;
        mm_segment_t addr_limit;
        struct restart_block restart_block;
        unsigned long previous_esp;
        __u8 supervisor_stack[0];
};

每个任务的thread_info结构在它的内核栈的尾端分配,其中的task域指向实际task_struct指针。
current_thread_info()->task;指向当前进程描述符
进程状态:
TASK_RUNNING
TASK_INTERRUPTIBLE——进程正在睡眠,某些条件达成后被唤醒
TASK_UNINTERRUPTIBLE——不可被打断
TASK_ZOMBIE——进程已结束,父进程未调用wait4(),子进程描述符仍被保留
TASK_STOPPED

set_task_state(task, state);设置进程状态
set_current_state(state)与set_task_state(current, state)等价;
进程描述符中还包括进程间的关系,指向父进程的task_struct parent以及称为children的子进程链表
3.2 进程创建
fork()+exec()——fork()通过拷贝当前进程创建一个子进程;exec()读取可执行文件并将其载入地址空间运行。
写时拷贝——父子进程共享同一拷贝,只有在需要写入时,数据才会复制,从而使各个进程拥有各自的拷贝
fork():
调用clone();
clone()调用do_fork();
do_fork()调用copy_process();
(1) 调用dup_task_struct()为新进程创建内核栈、thread_info结构和task_struct,与当前进程值相同;
(2) 父子进程开始区别,子进程描述符中很多成员清0或设置初始值;
(3) 子进程状态设为TASK_UNINTERRUPTIBLE,以保证不会投入运行;
(4) 调用copy_flags()更新task_struct的flags成员,表明进程是否拥有超级用户权限的PF_SUPERPRIV标志清0,表明进程还没调用exec()函数的PF_FORKNOEXEC标志被设置;
(5) get_pid()为新进程获取有效PID
(6) 根据传递给clone()的参数标志,拷贝或共享打开的文件、文件系统信息、信号处理函数、进程地址空间和命名空间等。
(7) 父子进程平分剩余时间片;
(8) copy_process()作扫尾工作并返回一个指向子进程的指针
clone()参数标志:

Flag
Meaning
CLONE_FILES
Parent and child share open files.
CLONE_FS
Parent and child share filesystem information.
CLONE_IDLETASK
Set PID to zero (used only by the idle tasks).
CLONE_NEWNS
Create a new namespace for the child.
CLONE_PARENT
Child is to have same parent as its parent.
CLONE_PTRACE
Continue tracing child.
CLONE_SETTID
Write the TID back to user-space.
CLONE_SETTLS
Create a new TLS for the child.
CLONE_SIGHAND
Parent and child share signal handlers and blocked signals.
CLONE_SYSVSEM
Parent and child share System V SEM_UNDO semantics.
CLONE_THREAD
Parent and child are in the same thread group.
CLONE_VFORK
vfork() was used and the parent will sleep until the child wakes it.
CLONE_UNTRACED
Do not let the tracing process force CLONE_PTRACE on the child.
CLONE_STOP
Start process in the TASK_STOPPED state.
CLONE_SETTLS
Create a new TLS (thread-local storage) for the child.
CLONE_CHILD_CLEARTID
Clear the TID in the child.
CLONE_CHILD_SETTID
Set the TID in the child.
CLONE_PARENT_SETTID
Set the TID in the parent.
CLONE_VM
Parent and child share address space.
3.3 线程
线程也拥有自己的task_struct,与普通进程的区别是内核线程没有独立的地址空间(mm指针为NULL)
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
一般情况下,内核线程会将创建的函数永远执行下去,该函数由一个循环构成,需要时唤醒并执行,完成任务会自行休眠。
3.4 进程终结
exit()
调用do_exit():
(1) 将task_struct中的标志成员设置为PF_EXITING
(2) 调用del_timer_sync()删除任意内核定时器;
(3) 调用acct_process()来输出记账信息;
(4) 调用__exit_mm()放弃进程占用的内存描述符mm_struct;
(5) exit_sem();
(6) 调用__exit_files(), __exit_fs(), exit_namespace(), exit_sighand() 分别递减文件描述符、文件系统数据、进程名字空间、信号处理函数的引用计数;
(7) 把task_struct中的exit_code成员中的任务退出代码设置为exit()提供的代码;
(8) 调用exit_notify()向父进程发送信号,将子进程的父进程重新设置为线程组中的其他进程或init进程,进程状态设置为TASK_ZOMBE
(9) 调用schedule()切换到其他进程
调用do_exit()后,线程已僵死,但系统保留了进程描述符。
删除进程描述符release_task():
(1) free_uid()减少进程拥有者的进程使用计数;
(2) unhash_process()从pidhash上删除该进程,同时从task_list中删除该进程;
(3) 将跟踪进程的父进程重设为其最初的父进程并将其从ptract list中删除;
(4) 调用put_task_struct()释放进程内核栈和thread_info所占的页,释放task_struct所占的slab高速缓存。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/85048/showart_1914063.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP