线程创建.png
    14635b1613d04df9f217c3508ae8524b.jpg

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