Chinaunix首页 | 论坛 | 博客
  • 博客访问: 285392
  • 博文数量: 49
  • 博客积分: 3083
  • 博客等级: 中校
  • 技术积分: 710
  • 用 户 组: 普通用户
  • 注册时间: 2007-07-27 08:22
文章分类

全部博文(49)

文章存档

2009年(8)

2008年(41)

分类: LINUX

2008-12-22 09:25:08

Kernel阅读手记之进程

 

每个进程都有独立的task_struct,里面包含了进程的相关信息,可以通过pid标记不同的进程。

do_fork负责处理clone(),fork(),vfork()系统调用,三个系统调用在使用do_fork时仅仅时标志不同

1、  clone_flags中没有CLONE_STOPPED标记时,定义一个静态的,子大部分时候用于读操作的计数器count,并设置初始值为100

2、  count大于0,并且printk_ratelimit()返回值不为0时,count1,输出信息

3、  如果是用户态调用的,则准备创建一个新的克隆子程序,内核态则不需要对trace做其他修改

4、  p设置成新复制的子进程。复制的东西有寄存器、和所有父进程环境中合适的部分。但是不运行此进程。

5、  p设置成功时,得到p的进程号交给nr

6、  处理带有CLONE_PARENT_SETTIDCLONE_VFORK标签的情况

7、  p运行前通知父进程准备运行p

8、  清除p的标签中的PF_STARTING

9、  clone_flags 中没有CLONE_STOPPED标签时,标记p,并设置p的状态为停止等待结束状态。否则,开始p这个进程

10、              通知父进程,当前P已经开始运行

11、              clone_flags中含有CLONE_VFORK标签时,如果当前进程是用户态时,停止计数直到当前completion的结束,通知其父进程,不含有CLONE_VFORK标签时,将nr的值设置为PTR_ERR(p)

12、              返回nr

 

 

copy_process()作用是创建进程的描述符及子进程执行所必须的其他数据结构,在do_fork()的第四步中使用

1、  clone_flags中有错误的参数时,返回错误代码

2、  使用security_task_create()clone_flags进行安全性检查,返回值赋值给retval,不为0时,返回错误

3、  retval设置成-ENOMEM

4、  调用dup_task_structcurrent的子进程分配进程描述符,将结果交给p,错误则返回ERR_PTR(retval)

5、  retval的值设置成-EAGAIN

6、  当前进程拥有者所拥有的进程的数量大于等于p->signal->rlim[RLIMIT_NPROC].rlim_cur,并且进程没有root权限,CAP_SYS_ADMINCAP_SYS_RESOURCE不被允许时,返回错误

7、  p->user__countprocesses以及p->group_info->usage增加1

8、  如果系统中的当前进程数大于系统上限时,或者无法得到其模块,或者linux所接受的二进制形式时,回滚操作并返回错误

9、  设置p->did_exec 的值为1 ,初始化p的参数

10、              将执行调度相关的设置交给一个cpu来做

11、              retval的值进行错误处理

12、              如果pid不是初始化之后的,设置retval -ENOMEM,并重新分配一个pid,当clone_flags中有CLONE_NEWPID标签时重新设置retval的值,同时进行错误处理

13、              当前运行的命名空间和新进程p的命名空间不相同时,重新设置retval的值为ns_cgroup_clone(p, pid),失败,则返回错误

14、              设置p的子进程的创建和释放iangde属性tid

15、              CLONE_PTRACE取消时,关闭系统调用

16、              设置当前进程的id为父进程id

17、              设置进程最后部分,在可能情况下运行cgroup callbacks,确保其可用,但是不唤醒

18、              用写锁锁上tasklist_list

19、              将当前进程的值赋值给p,锁住当前进程的siglock,当前进程的标志不为TIF_SIGPENGIND时, 报错返回

20、              clone_flags中有CLONE_THREAD标志时,复制当前进程的线程给p

21、              如果p不是idle时,设置p的兄弟进程,通知当前的子进程p已经创建成功正在使用中

22、              如果p是线程组的头一个线程时,如果标签中有CLONE_NEWPID标记,则设置p->nsproxy->pid_ns->child_reaperp。将当前进程的部分属性复制给p,并将p加入rcu队列。将p加入哈希序列,nr_threads1

23、              total_forks1,解除自旋锁和写锁,连接p,在p加入运行队列后调用一个新task

 

 

 

do_group_exit()退出属于current线程组的所有进程,接受进程的终止代码作为参数

1、   当所有线程的except ->group_exit_taskSIGKILL信号时,设置exit_codesig->group_exit_code

2、   或者dangerous当前线程组为空时,定义一个sighand_struct *const类型的 sighandcurrent->sighand,锁住其siglock,如果当前进程的signalexcept ->group_exit_taskSIGKILL信号时,设置exit_code的值为sig->group_exit_code,否则,设置sig->group_exit_code exit_code,并将sig的标签设置成 SIGNAL_GROUP_EXIT。杀死当前线程组中的其他进程

3、   解除自旋锁

4、   调用do_exit并传递进程的exit_code

 

 

do_exit()从内核数据结构中删除对终止进程的引用

1、  当前进程没有PF_EXITING时,设置PF_EXITING标签,尝试关闭进程上下文,设置当前的状态为不可中断,重新调度

2、  设置PF_EXITING给当前进程

3、  解除自旋锁

4、  更新task_struct 中的累积的时间和内存管理模块

5、  tsk->signal->live1,并将结果传给group_dead,不为0时,尝试释放ttyhrtimeritimers

6、  释放信号量、task->filestask->fs,退出线程,cgroup、线程锁、模块,通知相应的进程,并且在pid释放之后再检查链表和状态缓存,并清空。

7、  设置tsk标志为PF_EXITPIDONE,退出进程的i/o上下文,管道信息。关闭优先级,设置tsk的状态为TASK_DEAD

8、  调用schedule()调度程序运行

 

 

 

 

 

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