1.task_struct
linux进程数据结构task_struct在中定义,在32位机上大概有1.7KB大,所有task_struct通过slab分配存储空间并组成一个双向循环链表(2.6内核以前task_struct存储在内核栈的底部),为了快速查找进程,2.6内核在内核栈底部为每个task_struct对应分配一个thread_info结构,thread_info只有10个域,相对较小,其中struct task_struct * task指向对应的task_struct。
2.pid
pid的类型是pid_t,在很多情况下就是int,但是它的最大值一般设置为32768,在运行期间可以通过修改/proc/sys/kernel/pid_max来改变这个数值。
3.task state
linux中进程只能处于5种状态中的一种:
1.TASK_RUNNING 进程正在运行或者可以运行并处于就绪队列等待调度
2.TASK_INTERRUPTIBLE 进程等待事件发生或信号,可被事件或信号唤醒
3.TASK_UNINTERRUPTIBLE 进程等待事件发生,不能被信号唤醒
4.TASK_ZOMBIE 进程已结束,但其父进程没有通过wait()获取它的退出状态
5.TASK_STOPPED 进程没有运行或不能运行,这可能是由于收到SIGSTOP, SIGTSTP, SIGTTIN, or SIGTTOU信号引起
4.process context & interrupt context
process context是指进程调用系统调用或触发异常时,内核代替进程在内核空间执行,有进程相关
interrupt context是指内核进行中断处理,没有进程相关
5.clone(),fork(),vfork(),thread,kernel thread
linux内核中,线程和进程创建都是通过不同参数调用clone()完成的,clone()复制父进程的task_struct,并根据参数在父子进程的task_struct之间共享一些数据,从而完成不同的任务。
1.fork():是创建一个进程的系统调用,它被父进程调用而返回两次,一次在父进程中返回子进程pid,另一次在子进程中返回0。它通过clone(SIGCHLD, 0)实现。
2.vfork():和fork()几乎一样,唯一区别在于子进程没有拷贝父进程的页表项,父进程一直阻塞到子进程调用exec()或者exit(),子进程调用exec()或者exit()之前运行在父进程的地址空间中且不能写。它通过调用clone(CLONE_VFORK | CLONE_VM | SIGCHLD, 0)实现。
3.thread:linux中线程就是一个与父进程共享地址空间等信息的进程,并没有特殊的数据结构来表示线程,它通过clone(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, 0)实现。
4.kernel thread:是一类特殊的进程(如pdflush),仅仅运行在内核空间执行一些关键操作,它和普通进程的重要区别是没有地址空间,kernel thread也能像普通进程一样被调度和抢占。
阅读(1391) | 评论(0) | 转发(0) |