【问题标题】:GNU/Linux thread implementationGNU/Linux 线程实现
【发布时间】:2015-05-07 19:27:33
【问题描述】:

最近,我在“高级 Linux 编程”一书(http://www.advancedlinuxprogramming.com/alp-folder/alp-ch04-threads.pdf,第 4.5 章)中读到,在 GNU/Linux 上,POSIX 线程被实现为进程,并且有某种“管理器线程”可以做一些事情控制工作。

当我运行本书中的以下示例时:

#include <stdio.h>
#include <pthread.h>

void* thread_func(void *arg)
{
  fprintf(stderr, "thread: %d\n", (int)getpid());
  while(1);
  return NULL;
}

int main()
{
  fprintf(stderr, "main: %d\n", (int)getpid());

  pthread_t thread;
  pthread_create(&thread, NULL, thread_func, NULL);

  while(1);
  return 0;
}

我收到的主线程和子线程的 PID 相同,而书上说它可以不同,还有另一个 PID,对应于所谓的“管理器线程”。我试图找到有关此“经理线程”的一些信息,但事实证明这很困难。

UPD。我对我的程序的行为没有任何疑问,但是对于行为有一些困惑,书中解释了 - 特别是在哪些情况下它可能是正确的?

【问题讨论】:

  • 克隆系统调用手册页可以帮助linux.die.net/man/2/clone
  • 高级 Linux 编程 是一本非常好的书,但它可能早于 NPTL,这是最近的 glibc 拥有/使用的。
  • 对于有关技术的书籍,始终知道该书的出版时间,在本例中为“2001 年 6 月第一版”。声明已经过时了。

标签: c linux pthreads


【解决方案1】:

我已经收到了主线程和子线程相同的 PID

这是正常和预期的行为。您创建的这些线程共存于同一进程中,因此getpid() 返回该进程的 ID。如果要区分线程,请使用pthread_self()(POSIX 兼容,但不是系统范围唯一)或gettid()(特定于Linux)。

在Linux内部,所有进程和线程都由名为task的通用对象管理(由task_struct定义),每个任务都有自己的ID。然而,第一个任务是一个处理过程,因此称为任务组领导。 getpid() 返回那个任务组领导的PID。

因此,在您的情况下,thread_func() 线程打印其领导者的 PID,main() 任务和main() 线程打印自身的 PID。

我建议您深入研究内核内部。它提供了对此类事物的更清晰的视图 - 尝试例如 Robert Love 的书“Linux Kernel Development”。有关线程/进程/等的一些信息。可以在这里找到:http://www.win.tue.nl/~aeb/linux/lk/lk-10.html

【讨论】:

  • 问题是为什么在其他地方(例如,在系统上,在书中描述)这可能不是正常和预期的行为?是否取决于特定的内核实现?
  • 我不能为一本书说话,但也许示例是在旧版本的内核上运行的?根据clone() 手册页,线程组是在 Linux 2.4 中引入的。
  • @ars 这本书的日期是 2001 年,所以它似乎描述了 linux 上 pthreads 的旧实现,LinuxThreads 就是这种情况。
  • 为了完整起见,可能值得一提的是,pthread_self() 返回的值不保证在系统范围内唯一,但仅在进程范围内,因为gettid() 返回的值是系统-广泛独特。
【解决方案2】:

刚刚看了书上的相关内容和你分享的例子,很明显和POSIX threads on GNU/Linux的具体实现有关

In GNU/Linux, threads are implemented as processes. 

因此,每当您调用 pthread_create 来创建一个 新线程,Linux 会创建一个运行该线程的新进程。

所以在示例代码中,当您执行pthread_create(&amp;thread, NULL, thread_func, NULL); 时,实现会创建一个新进程来运行这个新创建的线程。此进程将具有不同的 PID(这是 getpid()call 显示的内容)。

所以,现在你已经有了 2 个进程,一个是在你运行程序时启动的主进程,另一个是系统创建的新进程以支持线程执行。

同样的实现还创建了另一个进程(在其实现内部),称为管理线程。这是在您调用pthread_create时创建的

【讨论】:

    猜你喜欢
    • 2014-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-12
    • 2015-04-09
    • 1970-01-01
    • 2011-11-28
    相关资源
    最近更新 更多