标签:位置 执行文件 thread 设备 app code 优化 osi 提升
[toc]
每个层次之间的通信的协议叫做接口(Interface)。
开发工具和应用程序在同一层,称之为操作系统应用程序接口(API: Application Programming Interface)。API由运行库来提供,什么样的运行库提供什么样的API。Linux下的glibc提供POSIX的API, Windows提供Windows的API。
运行库使用操作系统提供的系统调用接口。系统调用常常使用软件中断来实现。Linux常常使用0x80号中断。
操作系统的硬件接口的使用者,操作系统与硬件进行通信的协议称之为硬件规格。
操作系统的官方解释:操作系统 是一组控制和管理计算机系统中所有资源的程序的集合。
操作系统的功能:
处理机(CPU)管理
单道程序、 多道程序调度
因为CPU处理速度与I/O速度的极大差距,所以产生了多种CPU调度方式,比如分时系统,多任务系统。
存储管理
设备管理
文件管理
网络管理
程序简单装入内存: 分配连续的程序需要的全部的物理内存。
例如: PA 需要内存10M, PB需要内存100M, PC需要20M
将前10M分配给A, 10~110M分配给B,这样可以同时运行。
存在问题:
线程, 轻量级进程, 是程序执行流的最小单元。由线程ID,当前指令指针、寄存器集合和堆栈组成。
进程和线程之间的关系
一个进程由一个或者多个线程组成,各个线程之间共享进程级资源(打开的文件或者信号)和程序的内存空间(代码段、数据段、堆)。
为什么使用多线程:
数据共享方面的优势
线程调度方式: 优先级调度、轮转法
优先级调度中的几个概念:
频繁等待的线程称为IO密集型线程
很少等待的线程称为CPU密集型线程
一般来说,IO密集型的线程的优先级较之CPU密集型的线程的优先级要高。
线程优先级变更的方式:
所谓抢占就是在某个线程在时间片没有用完的前提下,强制从执行状态进入就绪状态。
不可抢占线程中也有线程主动放弃执行的情况:
不同于Windows系统, Linux系统对于多线程的支持并不是那么完善。
Linux对于每一个执行实体都称之为任务,这是一个单线程的进程,具有内存空间,执行实体。
具有着共享同一个内存空间的多任务构成了一个进程,这些任务也就成了进程的线程。
Linux创建线程的方式:
fork()函数产生一个与当前进程一样的新进程,产生的新进程与主进程之间共享着写时复制的内存空间。
exec()系列函数是使用一个新的可执行文件映像。
利用fork产生新进程,然后再新进程中使用exec来产生新任务。
还有一个函数是clone(),产生新任务,并从指定位置执行,可以继承父进程的某些可选资源。
多进程中对于非原子性操作,出现操作竞争,会出现重复写入,延迟读的情况。
原子性操作: 对于CPU来说是单指令操作。
提高线程安全性的方法:
可重入的概念:
过度优化问题:编译器对于程序的优化,使得并不能让程序按照我们想象的方式来进行。
例如单例模式:
volatile T *pInst = 0;
T *getInstance() {
if (pInst == NULL) {
lock();
if (pInst == NULL) {
pInst = new T;
}
unlock();
}
return pInst;
}
这个单例模式其实是有问题的,问题来源与CPU乱序执行。
C++中new包含两个步骤:
将内存首地址赋值给pInst
其中第二步和第三步是可以颠倒顺序的。
线程A 在先给pInst赋值后并没有完成构造,线程B这个时候调用getInstance会返回一个没有构造完成的T给用户使用。
解决办法:
#define barrier() __asm__ volatile ("lwsync")
volatile T *pInst = 0;
T *getInstance() {
if (pInst == NULL) {
lock();
if (pInst == NULL) {
T *temp = new T;
barrier();
pInst = temp;
}
unlock();
}
return pInst;
}
标签:位置 执行文件 thread 设备 app code 优化 osi 提升
原文地址:https://www.cnblogs.com/Alruddy/p/9123496.html