在linux中,线程与进程最大的区别就是是否共享同一块地址空间,而且共享同一块地址空间的那一组线程将显现相同的PID号。
在实际编程应用中,我们会很容易发现并证明,一组同源线程的PID都是一样的,但它们的PID真的一样么?
在linux中,线程的创建和普通进程的创建类似,只不过在调用clone()的时候需要传递一些参数标志来指明需要共享的资源:
-
clone(CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND,0);
上面的代码产生的结果和调用fork()差不多,只是父子俩共享地址空间、文件系统资源、文件描述符和信号处理程序。换个说法就是,新建的进程和它的父进程就是流行的所谓线程。 对比一下,一个普通的fork()的实现是:
而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_ttid[10];
-
-
void*thread_handler(void*arg)
-
{
-
printf("tid%d:%u,pid:%u\n",(int)arg,(unsigned)pthread_self(),
-
(unsigned)getpid());
-
while(1){
-
sleep(1);
-
}
-
returnNULL;
-
}
-
-
intmain(void)
-
{
-
inti,ret;
-
pid_tpid;
-
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内核设计与实现》
----
转自:linux线程的线程ID与其进程ID
分享到:
相关推荐
linux unix 进程 线程linux unix 进程 线程linux unix 进程 线程linux unix 进程 线程linux unix 进程 线程linux unix 进程 线程
Linux多线程Linux多线程Linux多线程Linux多线程Linux多线程Linux多线程Linux多线程
linux 进程和线程编程 pipe --原始管道 命名管道 消息队列 信号量 内存共享 线程编程
linux多线程编程.pdf
Linux多线程服务端编程,高清无水印!~
linux 进程 线程 fork 的深入思考 一道面试题的思考
linux系统下,C语言多线程多进程编程
linux系统下建立多线程程序设计,完成UDP网络通信的发送与接收,包括总结与源代码,实测效果可见链接https://blog.csdn.net/zxp121127/article/details/78506081
linux下的进程、线程
linux多线程编程 声明:本文是网上整理的资料,版权属其作者本人所有。 1 第一章 线程基础知识 2 一.什么是线程 2 二.线程的优点 2 三.线程的缺点 2 四.线程的结构 2 五.线程标识 2 六.线程的创建 3 七..线程...
在linux上分别用多进程和多线程实现的同步互斥操作(源代码)
代码目的是比较write和printf多路写性能。首先fork生成子进程,并且在子进程中重定向标准输出;然后在父子进程中各创建10个线程分别利用printf和write进行写操作;最后通过返回值比较两者性能。
Linux下多线程及多进程及同步与互斥编程详细介绍
Linux多线程服务端编程 Linux多线程服务端编程 Linux多线程服务端编程 Linux多线程服务端编程 Linux多线程服务端编程
作者: 陈硕 《Linux多线程服务端编程:使用muduo C++网络库》主要讲述采用现代C++在x86-64 ...掌握一种进程间通信方式和一种多线程网络编程模型就足以应对日常开发任务,编写运行于公司内网环境的分布式服务系统。
linux 系统的编程的源码,对初学者很有帮助。多线程、内存、信号量等程序。
多线程模拟进程调度多线程模拟进程调度多线程模拟进程调度多线程模拟进程调度
Linux 多线程编程笔记——简单、好记、好用说明:本代码参考麦子学院魏杰老师的Linux多线程编程 视频教程,整理有参考网上的做出修改,自己也可以参考网上比较好的例程
PPT文档及相应C源码 linux串口编程 linux进程间通信 linux进程间通信 linux多线程编程 linux网络编程
Linux下的多线程编程.pdf