1. current
内核有一个常用的常量current用于获取当前进程task_ struct 数据结构,它利用了内核栈的特性。首先通过SP寄存器获取当前内核栈的地址,对齐后可以获取struct thread info 数据结构指针,最后通过thread_ info->task 成员获取task_ struct 数据结构。
#define get_current() {current_thread_info()->task}
#define current get_current()
2. fork、vfork、clone的区别
fork实现:
do_fork(SIGCHLD, 0, 0, NULL, NULL);
vfork实现:
do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, 0, NULL, NULL);
clone实现:
do_fork(clone_flags, newsp, 0, parent_tidptr, child_tidptr);
内核线程:
do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn, (unsigned long)arg, NULL, NULL);
上面4种实现都是通过调用do_fork()函数来完成的,只是调用的参数不一样。fork 只使用SIGCHLD标志位,在子进程终止后发送SIGCHLD信号通知父进程。fork 是重量级调用,为子进程建立了一个基于父进程的完整副本,然后子进程基于此运行。为了减少工作量采用写时复制技术(copy on write, COW),子进程只复制父进程的页表,不会复制页面内容。当子进程需要写入新内容时才触发写时复制机制,为子进程创建一个副本。vfork 的实现比fork多了两个标志位,分别是CLONE VFORK和CLONE_VM。CLONE_VFORK表示父进程会被挂起,直至子进程释放虚拟内存资源。CLONE_VM表示父子进程运行在相同的内存空间中。clone用于创建线程,并且参数通过寄存器从用户空间传递下来,通常会指定新的栈地址(newsp)。
POSIX协议规定在一个进程内部多个线程共享一个PID。
struct