- 线程的创建
- 线程是由内核态和用户态合作完成的, pthread_create 是 Glibc 库的一个函数
- pthread_create 中
- 设置线程属性参数, 如线程栈大小
- 创建用户态维护线程的结构, pthread
- 创建线程栈 allocate_stack
- 取栈的大小, 在栈末尾加 guardsize
- 在进程堆中创建线程栈(先尝试调用 get_cached_stack 从缓存回收的线程栈中取用)
- 若无缓存线程栈, 调用
__mmap
创建 - 将 pthread 指向栈空间中
- 计算 guard 内存位置, 并设置保护
- 填充 pthread 内容, 其中 specific 存放属于线程的全局变量
- 线程栈放入 stack_used 链表中(另外 stack_cache 链表记录回收缓存的线程栈)
- 设置运行函数, 参数到 pthread 中
- 调用 create_thread 创建线程
- 设置 clone_flags 标志位, 调用
__clone
- clone 系统调用返回时, 应该要返回到新线程上下文中, 因此
__clone
将参数和指令位置压入栈中, 返回时从该函数开始执行
- 设置 clone_flags 标志位, 调用
- 内核调用
__do_fork
- 在 copy_process 复制 task_struct 过程中, 五大数据结构不复制, 直接引用进程的
- 亲缘关系设置: group_leader 和 tgid 是当前进程; real_parent 与当前进程一样
- 信号处理: 数据结构共享, 处理一样
- 返回用户态, 先运行 start_thread 同样函数
- 在 start_thread 中调用用户的函数, 运行完释放相关数据
- 如果是最后一个线程直接退出
- 或调用
__free_tcb
释放 pthread 以及线程栈, 从 stack_used 移到 stack_cache 中