进程:
进程就是处于执行期的程序以及它包含的资源总和。
线程是进程中的活动对象,每个线程拥有一个独立的程序计数器、进程栈和一组进程寄存器。
内核调度的是线程,而不是进程。
进程描述符:
内核的进程描述符为task_struct结构体,定义在<linux/sched.h>,进程描述符包含了一个进程的所有信息。包括:进程标识符、进程当前状态、栈地址空间、内存地址空间、文件系统、打开的文件、信号量等。
内核把进程的列表存放在叫做任务列表(task list)的双向循环链表,链表中每一项都是类型为task_struct的进程描述符。
进程描述符在内存的中存放位置比较有特点,由于系统需要频繁的获取当前进程描述符的地址,为提高效率,linux设置了current宏。
Linux在内核栈的末端存放一个特殊的结构体thread_info,在thread_info中的task存放着task_struck的位置,于是就能找到进程描述符。
进程状态:
task_struck中的state描述进程的状态
- TASK_RUNNING(运行):进程正在执行或者在等待队列中等待执行
- TASK_INTERRUPTIBLE(可中断):进程正在睡眠(就是被阻塞)等待某些条件达成,条件达成后内核就会把进程状态设置为运行,处在这个状态的进程可能会收到信号而提前被唤醒
- TASK_UNINTERRUPBLE(不可中断):在等待的过程中对信号不作响应,较少使用
- _TASK_TRACED:被其他进程跟踪的进程
- _TASK_STOPPED:停止执行,通常发生在进程收到SIGSTOP/SIGTSTP/SIGTTIN/SIGTTOU等信号后进入该状态
盗一张图来说明一下进程状态转换的过程:
设置当前进程的状态:
set_task_state(task,state);
必要时设置内存屏障来强制其它处理器重新排序(SMP)