网站建设中山优化,如何取消wordpress页脚,珠海企业官网设计制作,中国有哪些企业网站一、线程的概念
1.1 什么是线程
在一个程序里的一个执行路线就叫做线程#xff0c;更准确的定义是#xff1a;线程是“一个进程内部的控制序列”一切进程至少都有一个执行线程线程在进程内部运行#xff0c;本质是在进程地址空间内运行在Linux系统中#xff0c;在CPU眼中…一、线程的概念
1.1 什么是线程
在一个程序里的一个执行路线就叫做线程更准确的定义是线程是“一个进程内部的控制序列”一切进程至少都有一个执行线程线程在进程内部运行本质是在进程地址空间内运行在Linux系统中在CPU眼中看到的PCB都要比传统的进程更加轻量化透过进程虚拟地址空间可以看到进程的大部分资源将进程资源合理分配给每一个执行流就形成了线程执行流线程是进程内部的一个执行分支线程是CPU调度的基本单位加载到内存中的程序叫做进程进程 内核数据结构 进程代码和数据 我们在正文代码区中全部都是串行调用的在地址空间和地址空间上的虚拟地址本质上是一种资源当我们在创建进程的时候需要创建虚拟地址空间页表进程PCB等需要时间和空间比较麻烦。 在Windows中操作系统会创建线程控制块因为线程的数量很多所以需要先描述在组织。有一个缺点是非常复杂。所以Linux的设计者认为进程和线程都是执行流具有极度的相似性没有必要单独设计出数据结构和算法直接服用代码即可使用进程来模拟线程。 1.2 线程的优点和缺点
1.2.1 线程的优点
创建一个新线程的代价要比创建一个新进程小得多与进程之间的切换相比线程之间的切换需要操作系统做的工作要少的很多线程占用的资源要比进程少很多能充分利用多处理器的可并行数量但是线程的数量最好不要超过CPU的核数在等待慢速I/O操作结束的同时程序可执行其他的计算任务计算密集型应用为了能在多处理器系统上运行将计算分解到多个线程中实现I/O密集型应用为了提高性能将I/O操作重叠线程可以同时等待不同的I/O操作
1.2.2 线程的缺点
性能损失一个很少被外部事件阻塞的计算密集型线程往往无法与其他线程共享同一个处理器。如果计算密集型线程的数量比可用的处理器多那么可能会有较大的性能损失这里的性能损失指的是增加了额外的同步和调度开销但是可用的资源是不变的健壮性降低编写多线程需要更全面更深入的考虑在一个多线程程序中因时间分配上的细微偏差或者因为共享了不该共享的变量而造成不良影响的可能性是很大的换句话说线程之间是缺乏保护的缺乏访问控制进程是访问控制的基本粒度在一个线程中调用某些OS函数会对整个进程造成影响编程难度的提高编写和调试一个多线程程序比单线程程序困难的多
1.3 线程的异常
单个线程如果出现了除零野指针的问题会导致线程崩溃进程也会随着崩溃线程是进程的执行分支线程出现异常就类似于进程出现异常进而触发信号机制终止进程进程一旦终止该进程内的所有线程也就随机退出了
1.4 线程的用途
合理的使用多线程能提高CPU密集型程序的执行效率合理的使用多线程能提高IO密集型程序的用户体验
二、Linux进程 VS 线程 在以前的进程的理解中一个进程内部只有一个线程的进程但是在线程中一个进程中至少有一个线程线程是执行流。 那么进程是什么呢进程的内核角度上进程是承担分配系统资源的基本实体。我们不要站在调度的角度区理解进程而是应该站在资源的角度理解进程。
关于调度我们来谈一谈进程调度和线程调度都是什么 在进程中我们来进行CPU调度是需要重新加载进程的上下文数据和一个数据结构但是在线程中CPU调度只需要重新加载进程的PCB即可那么进程调度也就比线程调度需要多加载几个数据结构速度也没有慢到哪里。
那么究竟是什么让线程调度优于进程调度呢 CPU中有一个硬件叫做cache也叫做缓存有一个东西叫做时间相关性和空间相关性当CPU去执行代码时会将代码拷贝到缓存中并且会将该行代码下面的部分代码也拷贝到缓存中所以当我们进行进程调度的时候我们会发现原先拷贝到缓存中的代码不能使用因此需要我们重新去拷贝代码但是在进行线程调度的时候我们不需要进行将缓存中的代码进行替换因为线程是共享代码区的。
进程和线程的概念以及线程的共享区和私有区
进程是资源分配的基本单位线程是调度的基本单位
线程共享进程数据但是也拥有自己的一部分数据
线程ID一组寄存器栈errno信号屏蔽字调度优先级进程的多个线程共享 同一个地址空间因此Text SegmentData Text Segment 都是共享的如果定义一个函数在各个线程中都可以调用如果定义个全局变量在各个线程中都可以访问到各个线程还共享以下进程资源和环境
文件描述符每一种信号的处理方式SIG_ IGN、SIG_ DFL或者自定义的信号处理函数)当前工作目录用户ID和组ID
进程和线程的关系如下图 三、再谈地址空间 我们一般来说多个线程是共享的多个线程就是多个执行流这个多个执行流可以将共享的代码进行划分那么如何进行划分多个执行流呢 在之前我们谈及了页表那么我们现在还计算一下页表占用的空间大小在2^32位的地址空间中由于每一个地址空间需要进行虚拟地址到物理地址空间的转换所以一共需要2^32个地址转换在页表中一行上具有虚拟地址空间4字节物理地址空间4字节一些属性就按一行10个字节来计算但属性肯定不会这么少那么一共需要2^32 * 10 字节的空间换算一下是40GB的地址空间内存才4GB一个页表居然需要40GB的地址空间肯定不现实啊所以实际上的页表不是这么存储的。 在谈论页表之前我们需要先来看一看内存在操作系统中的结构是什么 内存也有结构吗内存在操作系统中不是直接的一整个大的空间而是由一份一份小的空间来进行操作的在文件系统中在磁盘存储中文件是有属性的以4KB为基本数据单元而在内存中的基本数据单位也是4KB那么一个4GB的内存有1048576个4KB个数据单元所以操作系统需要先描述在组织有属于他的结构体struct page有一个属性是flag我们可以将这个内存是不是内核的还是用户的是不是已经被使用了等等的属性用宏去定义在flag中声明。 那么页表在操作系统应该是怎样的结构呢我们可以将虚拟地址进行划分为三个部分一共是32比特一部分是10比特一部分是10比特一部分是12比特划分结果为下图所示