18

すべて、

以下のコードは「Unix環境での高度なプログラミング」からのもので、新しいスレッドを作成し、メインスレッドと新しいスレッドのプロセスIDとスレッドIDを出力します。

この本では、Linuxでは、pthreadが軽量プロセスを使用してスレッドをエミュレートするため、このコードの出力は2つのスレッドが異なるプロセスIDを持っていることを示していると述べています。しかし、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;
}
4

2 に答える 2

28

Linuxpthreadではclone、特別なフラグを付けてsyscallを使用しますCLONE_THREAD

syscallのドキュメントを参照してください。clone

CLONE_THREAD(Linux 2.4.0-test8以降)

CLONE_THREADが設定されている場合、子は呼び出しプロセスと同じスレッドグループに配置されます。CLONE_THREADの説明の残りの部分を読みやすくするために、「スレッド」という用語は、スレッドグループ内のプロセスを指すために使用されます。

スレッドグループは、単一のPIDを共有するスレッドのセットのPOSIXスレッドの概念をサポートするためにLinux2.4で追加された機能でした。内部的には、この共有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).
于 2012-05-01T02:49:24.797 に答える
7

Linuxは通常、pthreadの2つの実装を使用します。LinuxThreadsNative POSIX Thread Library(NPTL)ですが、前者はほとんど廃止されています。2.6のカーネルはNPTLを提供します。これは、SUSv3にはるかに近い適合性を提供し、特にスレッドが多い場合にパフォーマンスが向上します。
次のコマンドを使用して、シェルでのpthreadの特定の実装を照会できます。

getconf GNU_LIBPTHREAD_VERSION

Linuxプログラミングインターフェイスで、より詳細な実装の違いを取得することもできます。

于 2012-06-29T02:00:05.073 に答える