一尘不染

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

linux

所有,

下面的代码来自“ 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;
}

阅读 275

收藏
2020-06-03

共1个答案

一尘不染

在Linux上,请pthread使用clone带有特殊标志的syscall 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。

实际上,由于POSIX.1要求线程共享相同的进程ID
,因此Linux确实更改了其线程实现

   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).

2020-06-03