转自:http://blog./uid-24567872-id-100482.html linux线程的线程ID与其进程ID 2011-01-24 09:59:53 分类: LINUX 在linux 中,线程与进程最大的区别就是是否共享同一块地址空间,而且共享同一块地址空间的那? 蛔橄叱探韵窒嗤腜ID号。 在实际编程应用中,我们会很容易发现并证明,一组同源线程的PID 都是一样的,但它们的PID真的一样么? 在linux中,线程的创建和普通进程的创建类似,只不过在调用clone() 的时候需要传递一些参数标志来指明需要共享的资源: clone(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, 0); 上面的代码产生的结果和调用fork() 差不多,只是父子俩共享地址空间、文件系统资源、文件描述符和信号处理程序。换个说? ň褪牵陆ǖ慕毯退母附叹褪橇餍械乃较叱獭? 对比一下,一个普通的fork()的实现是: clone(SIGCHLD, 0); 而vfork()的实现是: clone(CLONE_VFORK | CLONE_VM | SIGCHLD, 0); 传递给clone() 的参数标志决定了新创建进程的行为方式和父子进程之间共享的资源种类。下面列举部分 clone()参数标志,这些是在<linux/sched.h>中定义的。 CLONE_FILES 父子进程共享打开的文件 CLONE_FS 父子进程共享文件系统信息 CLONE_SIGHAND 父子进程共享信号处理函数 CLONE_VM 父子进程共享地址空间 CLONE_VFORK 调用vfork(),所以父进程准备睡眠等待子进程将其唤醒 下面用一段程序测试一下,代码如下: 这段测试程序是主线程创建10个线程,并分别打印PID及TID。 #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> #include <sys/types.h> #include <string.h> pthread_t tid[10]; void * thread_handler(void *arg) { printf("tid%d:%u,pid:%u\n", (int)arg, (unsigned)pthread_self(), (unsigned)getpid()); while(1){ sleep(1); } return NULL; } int main(void) { int i, ret; pid_t pid; printf("main tid:%u,pid:%u\n", (unsigned)pthread_self(), (unsigned)getpid()); for(i = 0; i < 10; i++){ if((ret = pthread_create(&tid[i], NULL, thread_handler, (void *)i)) != 0){ fprintf(stderr, "pthread_create:%s\n", strerror(ret)); exit(1); } } sleep(3); pid = fork(); if(pid == 0){ printf("son tid:%u,pid:%u\n", (unsigned)pthread_self(), (unsigned)getpid()); while(1); sleep(1); } while(1) sleep(2); exit(0); } 编译运行: zx@zhangxu:~/lianxi/apue$ gcc -o test pthreadid.c -lpthread zx@zhangxu:~/lianxi/apue$ ./test main tid:3077888816,pid:2418 tid0:3077880688,pid:2418 tid1:3069487984,pid:2418 tid2:3061095280,pid:2418 tid3:3052702576,pid:2418 tid4:3044309872,pid:2418 tid5:3035917168,pid:2418 tid6:3027524464,pid:2418 tid7:3019131760,pid:2418 tid8:3010739056,pid:2418 tid9:3002346352,pid:2418 son tid:3077888816,pid:2429 从结果可以看出,测试程序中所有线程的PID都相同。 在另一个终端调用pstree -pu ├─gnome-terminal(1624,zx)─┬─bash(1628) │ ├─bash(1704)───pstree(2430) │ ├─bash(1927)───test(2418)─┬─test(2429) │ │ ├─{test}(2419) │ │ ├─{test}(2420) │ │ ├─{test}(2421) │ │ ├─{test}(2422) │ │ ├─{test}(2423) │ │ ├─{test}(2424) │ │ ├─{test}(2425) │ │ ├─{test}(2426) │ │ ├─{test}(2427) │ │ └─{test}(2428) 从中可以看出,每个线程的PID 其实是不同的,因为测试程序是理想状态,只有一个主线程在创建线程,所以PID 的值都是连续的。 参考资料:《linux内核设计与实现》
|
|