Linux 内核级线程修改。文本区?

Linux 内核级线程修改。文本区?,linux,multithreading,Linux,Multithreading,我不太理解用户级线程和内核级线程之间的区别。这就是我目前所知道的: 内核级线程 优点: 如果我们有多个处理器/内核,我们实际上可以同时运行线程(真正的并行性,因为内核调度器可以控制线程) 阻塞线程(例如I/O操作)不会阻塞所有线程 缺点: 上下文切换是在内核中进行的(这意味着它比在用户空间中慢) 用户级线程 优点: 更快的上下文切换 可以在应用程序中计划调度(而不是通过OS调度器) 缺点: 内核对线程一无所知,因此进程最多只能一次使用一个处理器/内核 如果一个线程发出阻塞调用,所有

我不太理解用户级线程和内核级线程之间的区别。这就是我目前所知道的:

内核级线程

优点:

  • 如果我们有多个处理器/内核,我们实际上可以同时运行线程(真正的并行性,因为内核调度器可以控制线程)
  • 阻塞线程(例如I/O操作)不会阻塞所有线程
缺点:

  • 上下文切换是在内核中进行的(这意味着它比在用户空间中慢)
用户级线程

优点:

  • 更快的上下文切换
  • 可以在应用程序中计划调度(而不是通过OS调度器)
缺点:

  • 内核对线程一无所知,因此进程最多只能一次使用一个处理器/内核
  • 如果一个线程发出阻塞调用,所有线程将再次被阻塞,因为内核不知道线程的存在,并且调度程序将向处理器/内核提供其他进程访问权限,即使此程序中的其他线程可以运行
据我目前所知,我无法回答这个问题:

创建内核级线程时,进程的.text(代码区域)如何修改

我的直觉告诉我,它不会改变,因为线程共享相同的地址空间,因此.text区域不会改变。我发现支持这个答案的另一个原因是.text区域是只读的。此外,所有其他区域将保持不变(.bss、heap等)。唯一会改变的是堆栈

然而,我想确定这是正确的答案


注意:我主要讨论linux内核上的线程(对windows线程了解不多)

用户级线程在linux中实际上并不存在。无论何时使用pthread_创建新线程,都会创建相应的内核级线程。使用
strace
应该很清楚,无论何时创建新线程,都会调用
clone()
系统调用

在任何情况下,所有线程都共享.text、.data和.bss节。
他们唯一不共享的是他们的堆栈。(是的,是的,还有线程局部变量。我们不要讨论这个。)

Linux中实际上不存在用户级线程。无论何时使用pthread_创建新线程,都会创建相应的内核级线程。使用
strace
应该很清楚,无论何时创建新线程,都会调用
clone()
系统调用

在任何情况下,所有线程都共享.text、.data和.bss节。
他们唯一不共享的是他们的堆栈。(是的,是的,还有线程局部变量。我们不要讨论这个。)

这里可能会询问4种不同类型的线程

  • 由内核本身创建的线程,用于处理后台任务
  • fork()
    syscall分叉的进程
  • pthread线程,由用户使用Linux
    clone()
    syscall创建,但由内核管理
  • 完全在内核调度程序之外运行的“绿色”线程
  • 下面的回答假设本文中提到的“用户级”线程是pthread类型,而不是“绿色”类型

    编辑:我认为@Hristo是正确的,OP谈论的是“绿色”线程,或者混淆了两者

    这个答案假设您谈论的是使用
    pthread\u create()
    创建的线程。还有一些是由用户空间调度的,内核不知道的。我将把我的答案留给后人


    用户线程==绿色线程

    所谓的“绿色线程”根据定义是完全由VM处理而不涉及内核的线程

    “用户级”内核对线程一无所知,因此最多一次进程将使用一个处理器/内核

    如果一个线程发出阻塞调用,所有线程将再次被阻塞,因为内核不知道线程的存在

    不会。只要使用正确的原语,阻塞调用就会导致线程进入等待队列,并运行另一个绿色线程

    创建内核级线程时,进程的.text(代码区域)如何修改

    在绿色线程中,它们都使用相同的代码区域

    此外,所有其他区域将保持不变(.bss、heap等)


    用户线程==pthreads

    使用
    pthread\u create()
    “用户线程”,它们与“内核”线程之间几乎没有区别。linux内核使用
    clone()
    系统调用将用户级线程作为单独的内核进程来实现
    clone()
    创建一个与父进程使用相同内存空间的新进程,而
    fork()
    使用父进程内存的副本创建一个新进程

    “用户级”内核对线程一无所知,因此最多一次进程将使用一个处理器/内核

    不,这是不对的。内核与任何其他进程一样管理用户级线程,因为它具有上下文切换和在多个CPU上调度各种用户级线程的能力,等等

    如果一个线程发出阻塞调用,所有线程将再次被阻塞,因为内核不知道线程的存在

    否,一个线程可以阻塞,其他线程将继续运行。同样,这属于pthread样式的线程

    创建内核级线程时,进程的.text(代码区域)如何修改

    创建新线程时,它将继承其父线程的内存分段表。