所有
下面的代码来自“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;
}
答案 0 :(得分:23)
在Linux上pthread
使用带有特殊标记clone
的{{1}}系统调用。
请参阅CLONE_THREAD
系统调用的documentation。
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执行change its thread implementation,因为POSIX.1 requires个线程共享相同的进程ID。
clone
答案 1 :(得分:6)
Linux通常使用两种pthread实现:LinuxThreads和Native POSIX Thread Library(NPTL),尽管前者基本上已经过时了。 2.6中的内核提供了NPTL,它提供了与SUSv3更接近的一致性,并且在有许多线程时表现更好。
您可以使用命令在shell下查询pthread的具体实现:
getconf GNU_LIBPTHREAD_VERSION
您还可以在The Linux Programming Interface中获得更详细的实施差异。