如何在linux内核3.2中实现pthread?

jil*_*luo 14 linux pthreads

所有,

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

在本书中,它表示在linux中,此代码的输出将显示两个线程具有不同的进程ID,因为pthread使用轻量级进程来模拟线程.但是当我在Ubuntu 12.04中运行此代码时,它有内核3.2,打印相同的pid.

那么,新的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;
}
Run Code Online (Sandbox Code Playgroud)

Zif*_*ong 23

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

查看文档clone系统调用.

CLONE_THREAD(自Linux 2.4.0-test8开始)

如果设置了CLONE_THREAD,则子节点与调用进程放在同一个线程组中.为了使CLONE_THREAD的剩余讨论更具可读性,术语"线程"用于指代线程组内的进程.

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

事实上,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).
Run Code Online (Sandbox Code Playgroud)


WiS*_*GaN 5

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

getconf GNU_LIBPTHREAD_VERSION

您还可以在Linux编程接口中获得更详细的实现差异.