

- 线程的创建
 - 线程是由内核态和用户态合作完成的, 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 中 
 
