| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> 【linux线程(壹)】——初识线程(区分线程和进程,线程创建的基本操作) -> 正文阅读 |
|
[系统运维]【linux线程(壹)】——初识线程(区分线程和进程,线程创建的基本操作) |
目录 📚?1. 线程和进程📚?1.1 进程的基本概念进程是分配系统资源的基本单位,当你运行程序的时候,系统就会给你创建进程,并为它分配各类资源,如进程地址空间,页表,进程控制块等资源,此时此时进程内部会伴随着一个执行控制序列让cpu去执行进程的代码和数据,这个进程最初的控制序列是进程内的主线程。 📚?1.2 线程的基本概念线程是进程里面单一的执行控制序列(执行流),也是cpu调度的基本单位(分配给cpu执行最小单位),假如进程的运行是为了完成某个任务,线程是该任务的许多子任务之一,线程的创建,操作系统并不会给它分配内存资源,进程中所有线程共享所属进程地址空间上的资源。如果进程里只有一个线程,也就是只有一个线程在cpu中执行该进程的代码和数据。如果有多个线程,那么这些线程轮流在cpu中执行该进程的代码和数据。 引用知乎上的一个比喻: 1.单进程单线程:一个人在一个桌子上吃菜。 一个线程只属于一个进程,一个进程可以拥有多个线程,线程之间可以并发执行。 在linux中,线程是在进程的基础改的,线程的控制块也是pcb(进程控制块是pcb),只是当我们在一个进程内部多创建一个线程的时候,不需要为线程创建进程地址空间,只需要多创建一个pcb,然后线程的pcb指向原本的进程所属的资源,这样线程就可以共享进程空间上的所有资源。 在linux内核中,是区分不出来进程还是线程的,因为线程和进程的控制块都是pcb。 单线程的进程:只有一个pcb 多线程的进程:多个pcb 栈区是主线程的私有栈,其它线程的私有栈在共享区域中的线程库里面,各个线程运行的代码都在代码区中,在动态库中,每个新创建的线程都有struct pthread和线程局部存储和线程的私有栈,struct pthread存储的是线程基本属性,线程的局部存储的是寄存器的数据。 📚 1.3?线程的优点
📚?1.4 线程的缺点
📚 1.5?线程的私有资源线程共享进程中的数据,但是它也有自己的数据:
📚 1.6?线程在进程共享的资源线程除了共享所属进程的地址空间和页表外,还共享以下进程资源;
📚?2. 线程的基本操作📚 2.1?线程的创建每个进程创建的时候都会伴随着一个线程的产生,这个线程叫做主线程,如果我们想要在一个进程里面多创建一个新的线程去执行其它任务,那么我们可以用pthread_create进行创建。
创建新的线程后,主线程和新线程并发执行的,且新线程和主线程的进程pid都是一样的,说明他们都是在同一个进程内运行,只是执行的路线不同。 ? 📚 2.2 ps -aL查看LWP,每个线程都有一个LWP,这个LWP是cpu调度的基本单位,之前我们没学过线程,会认为pid是cpu调度基本单位,实际cpu调度是按LWP进行调度的。有些线程LWP不同,但是pid是相同的,这些线程同属于一个进程。 📚?2.3 线程退出?return?在线程的起始函数中遇到return,则该线程退出,线程调用的函数不算线程退出。如果是在main函数中return,则整个进程都退出。
pthread_exit(void* value_ptr)pthread_exit在线程调用的任何一个函数中执行都会使该线程退出。
? 📚 2.4??线程取消
功能:取消线程,使该线程退出,可以让一个线程取消另一个线程,也可以线程自己取消自己。 被取消的线程的退出码是-1?.
过程:? 📚 2.5 线程的等待线程等待的函数:
接下来我们写一个程序,让主线程创建新线程并等待新线程:
运行过程:? ?线程等待的必要性
线程等待只能获得线程正常终止的退出码,为什么线程异常终止收到的信号不能通过线程等待来获取? 📚?2.6 线程的分离线程等待是阻塞的,假设主线程在等待新线程退出并获取它的退出码之前,主线程是不会运行的。 如果不关心线程的返回值,join是一种负担,那么我们可以将线程分离,即告诉操作系统,被分离的线程退出后自动释放资源。
? ?新线程的自我分离:
pthread_self() 获取自身的线程id 📚?3. 线程ID及进程地址空间布局在用户层面的标识线程的id使pthread_t,而在之前说的LWP是cou进行调度线程的 基本单位,那么调度线程后,我们还需要知道该线程的私有栈位于在进程的地址空间上的哪个位置,这时候就需要有一个地址将它表示标识(这时linux的实现)。 对于linux而言的NPTL实现而言,pthread_t类型本质是进程地址空间上的一个虚拟地址。 NPTL是一个linux的一个原生线程库,该原生线程库是一个动态库,所有创建的新线程都是在这个动态库中维护,动态库通过页表映射到进程的地址空间上共享内存的区域上。线程pthread_t是线程在进程地址空间上的共享内存上的起始地址。pthread_t属于用户数据,因为它位于用户空间上的。每个线程可以通过pthread_t可以找到该线程的在进程地址空间上的起始位置,通过该起始地址,我们就可以找到新线程的struct_pthread,线程的局部存储,线性栈,struct_pthread是每个线程的私有栈,线程的局部存储保存的线程的上下文数据,线程栈是每个线程的私有栈。所以进程内部的切换线程,只需要将线程的cpu的上下文代码,和临时数据保存到线性局部存储,然后再共享内存上切换到一个线程。 ldd test 查看test关联的动态库 ,test是关联libpthread.so.0这个动态库。 ?种一颗树最好是10年前,其次是现在!! 感谢大家的观看,如果可以的话,麻烦点点关注和赞呗! |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/16 8:30:40- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |