linux查看最大线程数,图解linux32位平台下进程线程长什么样子

 2023-09-21 阅读 20 评论 0

摘要:目录0.linux的进程线程1.单线程的进程2.多线程的进程3 总结3.1 公共之处3.2 差异之处4.好的图解文章推荐4.1 深入理解linux内核中的栈4.2 进程虚拟内存管理4.3基础知识系列 0.linux的进程线程 程序是某种格式的可执行文件,是和os相匹配的。比如windows下的程序是exe格

目录

        • 0.linux的进程线程
        • 1.单线程的进程
        • 2.多线程的进程
        • 3 总结
          • 3.1 公共之处
          • 3.2 差异之处
        • 4.好的图解文章推荐
          • 4.1 深入理解linux内核中的栈
          • 4.2 进程虚拟内存管理
          • 4.3基础知识系列

0.linux的进程线程

程序是某种格式的可执行文件,是和os相匹配的。比如windows下的程序是exe格式的可执行文件,unix下的程序是elf可执行文件。具体些,就是比如linux下main.c里只写了一个main函数,gcc -c main.c编译输出的elf格式的可执行文件a.out。那么,a.out就是程序。
线程是程序的一个执行流。 这个怎么理解?执行流? 程序里面可以包含很多线程,线程其实就是程序中的函数,有的是无限循环,有的是开环顺序执行完就退出了,有的是有条件的循环函数。 每个线程函数都被编译器编译成一堆对应架构的指令集的指令。程序是一堆指令的集合——而这一堆指令里包含了一个个线程函数的执行指令。所以说“线程是程序的一个执行序列”——执行序列就是指的是线程函数的执行指令,它只是程序中的一部分。
进程是程序的实例化。程序相当于类,进程相当于对象。说的就是面向对象中的类的实例化。什么是实例化?就是创建一个对象。创建一个对象又是什么?就是实例化。哈哈,循环了。但其实创建对象就是类的实例化,类的实例化就是开辟一个内存块。 同理,程序的实例化 就是将可执行文件加载到内存中并可被CPU执行。 比如在windows下,你双击某个exe格式的文件xxx,比如在unix和类unix下,你在shell中执行某个elf格式的文件——敲命令./xxx。这两种行为导致的结果就是:激活OS内核可执行文件加载器把可执行文件xxx加载到内存,然后为它开辟进程地址空间,再把进程栈、线程栈等资源准备好,然后跳入到main函数去执行(主线程),在main函数中创建了很多线程。程序就这样运行起来了。当然你可以重复实例化同一个可执行程序,即可以打开多个一模一样功能的进程。比如你可以在windows下登陆2个qq——双击一次qq登陆一个账号,再双击一次qq再登陆另一个小号。这运行的2个qq是2个进程,但是同一个程序——同一个可执行文件qq——它在内存中实例化了2个对象。unix类似。

但linux不区分进程线程的,都是task_struct
数据结构的角度看:
linux进程是一个task_struct或一组task_struct的集合。
linux线程是一个task_struct。

1.单线程的进程

单线程的进程
单线程的进程就是只有一个main函数且main函数里面没有调用glibc/uclibc等运行时库的pthread_create接口去创建线程。

linux查看最大线程数。由上图可以看到:
(1)主线程栈(也叫进程栈)是在栈区的。主线程栈是向下增长的,是满递减栈。 栈区最大是8MB,这是个内核宏,可设。主线程栈是在8MB内,唯一一个可以访问未映射区而不会段错误的一个地址空间。
(2)mm指向进程地址空间(每个进程的地址空间是唯一的,所以表示它的内存描述符指向的结构体内存块也是唯一的,是为单例模式)。单进程单线程相当于一个独门独院,一个人独享风景,很爽啊!
(3)主线程一般是main函数——因为c/c++规定一个程序只能有一个main函数。
(4)pid是线程号,tgid是进程号。主线程的pid和tgid是相等的。
(5)group_leader指向主线程,即自己。

2.多线程的进程

多线程的进程
多线程的进程就是只有一个main函数,但在main函数里面调用了glibc/uclibc等运行时库的pthread_create接口创建了很多很多线程。

可以看到:
(1)主线程栈(也叫进程栈)是在栈区的。主线程栈是向下增长的,是满递减栈。 栈区最大是8MB,这是个内核宏,可设。主线程栈是在8MB内,唯一一个可以访问未映射区而不会段错误的一个地址空间。
(2)普通线程栈是在mmap区的,每个线程栈是8MB+4KB的大小,其中4KB是隔离区域,线程栈不是向下生长的,只是后进先出LIFO的数据结构。
(3)主线程一般是main函数——因为c/c++规定一个程序只能有一个main函数。
(4)pid是线程号,tgid是进程号。主线程的pid和tgid是相等的,其他线程的pid号和tgid是不同的。注意:ps命令看到的PID是task结构体里的tgid,即进程号,LWP才是线程号pid。 不要奇怪,我猜这可能是历史原因,因为早期是没有支持线程的,后来支持线程了,怎么表示线程进程号?只好用pid来表示线程号了,增加tgid表示进程号吧!
(5)group_leader指向主线程。你看所有普通线程的group_leader都指向主线程。
(6)mm指向进程地址空间(每个进程的地址空间是唯一的,所以表示它的内存描述符指向的结构体内存块也是唯一的,是为单例模式)。主线程创建时会开垦这个地盘,其他线程直接领包入住。好有一比,这个线程你属于哪个国家的?多个线程就好比多个人都是中国人,进程地址空间就相当于中国的地理版图。

3 总结

3.1 公共之处

(1)主线程栈(也叫进程栈)是在栈区的。主线程栈是向下生长的,是个满递减栈。栈区最大是8MB,这是个内核宏,可设。主线程栈是在8MB内,唯一一个可以访问未映射区而不会出现段错误的一个特殊空间地址。
(2)mm指向进程地址空间。好有一比,这个线程你属于哪个国家的?多个线程就好比多个人都是中国人,进程地址空间就相当于中国的地理版图。mm还用来区分是进程切换还是线程间切换。可参见相关博客。
(3)主线程一般是main函数——因为c/c++规定一个程序只能有一个main函数。
(4)pid是线程号,tgid是进程号。主线程的pid和tgid是相等的。
(5)group_leader指向主线程。你看所有普通线程的group_leader都指向主线程。

3.2 差异之处

(1)栈的差异。多线程的进程比单线程的进程多了其他的普通线程和普通线程栈。主线程栈在栈区,向下生长。普通线程栈在mmap区,一般是由glibc/uclibc等运行时库调用mmap开辟的8MB+4KB大小的区域,不是向下生长,只是后进先出的数据结构,应该也可以理解成向下生长吧,这块还得搜索相关资料,深入理解。
(2)

4.好的图解文章推荐

4.1 深入理解linux内核中的栈

深入理解linux内核中的栈
我喜欢的是它把linux的task_struct结构体的mm成员指向的mm_struct内存块与进程地址空间的映射图给画出来了!太棒了!截图如下:
很棒的task与进程地址空间映射图

4.2 进程虚拟内存管理

一个进程可以有多个线程,进程虚拟内存管理
这个画的又丰富了些。如下截图:
进程虚拟内存管理

4.3基础知识系列

cpu与mmu
讲的非常棒的图,截图如下:
在这里插入图片描述在这里插入图片描述

linux c 虚拟地址转真实地址
很不错,截图如下:
在这里插入图片描述

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/2/81604.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息