pthread在linux kernel 3.2中是如何实现的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10392800/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 06:06:20  来源:igfitidea点击:

How does pthread implemented in linux kernel 3.2?

linuxpthreads

提问by jiluo

all,

全部,

The code below comes from "Advanced Programing in Unix Environment", it creates a new thread, and prints the process id and thread id for main and new threads.

下面的代码来自“Unix 环境中的高级编程”,它创建一个新线程,并打印主线程和新线程的进程 ID 和线程 ID。

In the book, it said that in linux, the output of this code would show that two threads have different process ids, because pthread uses lightweight process to emulate thread. But when I ran this code in Ubuntu 12.04, it has kernel 3.2, printed the same pid.

书中说在linux下,这段代码的输出会显示两个线程有​​不同的进程id,因为pthread使用轻量级进程来模拟线程。但是当我在 Ubuntu 12.04 中运行这段代码时,它有内核 3.2,打印了相同的 pid。

so, does the new linux kernel change the internal implementation of pthread?

那么,新的linux内核是否改变了pthread的内部实现呢?

#include "apue.h"
#include <pthread.h>

pthread_t ntid;

void printids(const char *s) {
  pid_t     pid;
  pthread_t tid;
  pid = getpid();
  tid = pthread_self();
  printf("%s pid %u tid %u (0x%x)\n",
         s, (unsigned int)pid, (unsigned int)tid, (unsigned int)tid);
}

void *thread_fn(void* arg) {
  printids("new thread: ");
  return (void *)0;
}

int main(void) {
  int err;
  err = pthread_create(&ntid, NULL, thread_fn, NULL);
  if (err != 0)
    err_quit("can't create thread: %s\n", strerror(err));
  printids("main thread: ");
  sleep(1);
  return 0;
}

采纳答案by Zifei Tong

On Linux pthreaduses the clonesyscall with a special flag CLONE_THREAD.

在 Linux 上pthread使用clone带有特殊标志的系统调用CLONE_THREAD

See the documentationof clonesyscall.

查看文档clone系统调用。

CLONE_THREAD (since Linux 2.4.0-test8)

If CLONE_THREAD is set, the child is placed in the same thread group as the calling process. To make the remainder of the discussion of CLONE_THREAD more readable, the term "thread" is used to refer to the processes within a thread group.

Thread groups were a feature added in Linux 2.4 to support the POSIX threads notion of a set of threads that share a single PID. Internally, this shared PID is the so-called thread group identifier (TGID) for the thread group. Since Linux 2.4, calls to getpid(2) return the TGID of the caller.

CLONE_THREAD(从 Linux 2.4.0-test8 开始)

如果设置了 CLONE_THREAD,则子进程将被放置在与调用进程相同的线程组中。为了使 CLONE_THREAD 的其余讨论更具可读性,术语“线程”用于指代线程组中的进程。

线程组是 Linux 2.4 中添加的一项功能,用于支持共享单个 PID的一组线程的 POSIX 线程概念。在内部,此共享 PID 是线程组的所谓线程组标识符 (TGID)。从 Linux 2.4 开始,对 getpid(2) 的调用将返回调用者的 TGID。

And in fact, Linux do change its thread implementation, since POSIX.1 requiresthreads share a same process ID.

事实上,Linux 确实改变了它的线程实现,因为POSIX.1 要求线程共享相同的进程 ID。

   In the obsolete LinuxThreads implementation, each of the threads in a process
   has a different process ID.  This is in violation of the POSIX threads
   specification, and is the source of many other nonconformances to the
   standard; see pthreads(7).
   In the obsolete LinuxThreads implementation, each of the threads in a process
   has a different process ID.  This is in violation of the POSIX threads
   specification, and is the source of many other nonconformances to the
   standard; see pthreads(7).

回答by WiSaGaN

Linux typically uses two implementations of pthreads: LinuxThreadsand Native POSIX Thread Library(NPTL), although the former is largely obsolete. Kernel from 2.6 provides NPTL, which provides much closer conformance to SUSv3, and perform better especially when there are many threads.
You can query the specific implementation of pthreads under shell using command:

Linux 通常使用 pthread 的两种实现:LinuxThreadsNative POSIX Thread Library(NPTL),尽管前者在很大程度上已经过时了。2.6 的内核提供了 NPTL,它提供了更接近 SUSv3 的一致性,并且在有很多线程时表现更好。
可以使用命令查询shell下pthreads的具体实现:

getconf GNU_LIBPTHREAD_VERSION

getconf GNU_LIBPTHREAD_VERSION

You can also get a more detailed implementation difference in The Linux Programming Interface.

您还可以在The Linux Programming Interface 中获得更详细的实现差异。