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