linux进程管理 初稿(Version 2.6.32)
定义
关于process,一个经典的定义是:
A process is a program in the midest of execution.
进程是对IO设备、处理器和主存的抽象,操作系统给每个进程提供它们独占CPU和主存的幻觉。
进程在内核中的表示
内核为每个进程维护一个进程描述符(struct task_struct)结构,它的定义在./include/linux/sched.h中。在这个结构中记录了描述进程状态的信息,如:打开文件表,进程地址空间,待决信号,进程的状态。。。
struct task_struct {
struct files_struct *files;
struct mm_struct *mm;
struct signal_struct *signal;
volatile long state;
...
};
进程状态
state描述了当前进程的状态,进程可能处于五种情况之一:
- TASK_RUNNING
- TASK_INTERRUPTIBLE
- TASK_UNINTERRUPTIBLE
- __TASK_TRACED
- __TASK_STOPPED
注意进程处于TASK_UNINTERRUPTIBLE状态时它不能被信号唤醒。
进程的创建
Linux使用clone()系统调用来实现进程的创建,它会调用do_fork()(./kernel/fork.c),do_fork()又会调用copy_process(),这里包含了真正有趣的工作:
// This creates a new process as a copy of the old one,
// it copies the registers, and all the appropriate
// parts of the process environment.
static struct task_struct *copy_process(unsigned long clone_flags,
unsigned long stack_start, struct pt_regs *regs,
unsigned long stack_size, int __user *child_tidptr,
struct pid *pid, int _trace)
{
struct task_struct *p;
// 检查flags是否合法
p = dup_task_struct(current); // 分配thread info/kernel stack和process descriptor,内容与父进程一致
// 检查进程资源的限制
// 子进程设置不同于父进程的一些字段
sched_fork(p, clone_flags); // 设置调度相关的字段
// 根据传递的flags标志确定哪些资源是共享,哪些资源需要复制
copt_semundo(clone_flags, p);
copy_files(clone_flags, p);
copy_fs(clone_flags, p);
copy_signal(clong_flags, p);
copy_mm(clone_flags, p);
copy_namespaces(clone_flags, p);
copy_io(clone_flags, p);
// 初始化内核栈
copy_thread(clone_flags, stack_start, stack_size, p, regs);
pid = alloc_pid(p->nsproxy->pid_ns);
...
}
由于使用了COW(Copy on Write)技术,fork()带来的开销其实只有父进程页表的复制和新进程描述符的建立。
Linux中的线程
linux并没有实现一个独立的线程概念,线程是通过进程来实现的,多个线程可以共享一些资源。
在unix系统中
线程的终止
A sad story,到了要结束的时候。结束的处理工作由do_exit()(./kernel/exit.c)来执行:
void do_exit(long code)
{
exit_signals(tsk); //设置PF_EXITING标志
exit_mm(tsk); //释放进程地址空间
exit_sem(tsk);
exit_files(tsk);
exit_fs(tsk);
exit_thread();
...
exit_notify(tsk, group_dead);
schedule();
}