目录
- CPU
- 核心
- 超线程技术
- 进程
- 线程
- 并行与并行
- 进程与线程的区别
- 操作系统如何切换进程
- 多线程中的概念
- 守护进程概念
CPU
一个冯·诺伊曼结构的计算机主要硬件有主板,CPU,内存,外存,显卡,网卡,声卡,电源,键盘,鼠标,显示器等
CPU是一块超大规模的集成电路,h是计算机的运算核心和控制核心。
由三大部分组成运算器,寄存器,寄存器。
CPU的个数很容易得到,多CPU通过主板上的总线进行连接。
核心
核心又称内核(后文在习惯上讲核心称为内核),是CPU的组成部分,用来完成所有的计算,储存等任务,由单晶硅制成
超线程技术
这里需要知道的是在一个CPU中可能存在多个核心,这些核心是相对独立的CPU核心单元组
而超线程技术则是利用代码手段在一个物理核上模拟两个逻辑核,两个逻辑核会有各自独立的寄存器和APIC,但是共享物理核的执行资源
可以看到这一个CPU是只有六个物理内核,但是由于超线程技术OS认为它有12个内核
进程
进程是OS进行资源(CPU,内存,磁盘,IO,带宽等)分配的最小单位
- 进程的特征:
- 动态性:进程是程序的一次执行过程,是临时的,有生命期的,是动态产生,动态消亡的;
- 并发性:任何进程都可以同其他进程一起并发执行;
- 独立性:进程是系统进行资源分配和调度的一个独立单位
- 结构性:进程由程序、数据和进程控制块三部分组成。
线程
值得一提的是,在早期的操作系统中并没有线程的概念 ,进程是能拥有资源和独立运行的最小单位,也是程序执行的最小方式。任务调度采用的是时间片轮转的抢占式调度方式,而进程是任务调度的最小单位,每个进程都有各自独立的一块内存,使得各个进程之间内存地址相互隔离。
随着时代改变,由于进程与进程之间消耗过大,不在能满足人们的需要,线程的概念就由此诞生:
线程是程序执行中一个单一的顺序控制流程,是程序执行流的最小单元,是处理器调度和分派的最小单位。
并发与并行
- 并发:当有多个线程在操作时,且只有一个CPU时(由于只有一个CPU所有它不能同时运行一个以上的线程),所以人们采取的方法是把CPU运行时间分为若干个时间段,将时间段分配给各个线程执行,在一个时间段的线程代码运行时,其他线程处于挂起状,这种方式称为并发。
- 并行当一个系统有一个以上CPU时,则线程的操作有可能并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程不抢占CPU资源同时进行,这种方式称为并行。
由于CPU上的线程切换很快,所以并发看起来像是时运行
进程与线程的区别
- 线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位;
- 一个进程可以由一个或多个多个线程组成;
- 进程之间是相互独立的,而同一进程下的各个线程之间共享程序的内存空间(包括代码段、数据集、堆等)及一些进程级的资源(如打开文件和信号);
- 线程上下文切换要比进程快得多
操作系统如何切换进程
调度选择下一个进程,得到下一个进程的PCB(Process Control Block),把上一个进程的执行现场保存起来,把下一个进程的现场覆盖到CPU对应的寄存器中去。多进程如何交替?如何切换?把上一个进程的执行现场保存起来,把当前CPU中的寄存器信息等保存到上一个进程的PCB中,把选好的要执行的进程(由进程调度确定)的PCB中的各寄存器信息恢复到当前CPU的寄存器中。
多进程中的概念
由于在同一时间只能运行一个线程,在多线程环境下线程的抢占式运行容易出现线程安全问题
人们因此想出了互斥机制来解决线程不安全的问题
而互斥机制的实现是通过互斥锁实现的,基本步骤为:
- 加锁
- 执行临界区代码
- 释放锁
互斥锁又叫挂起等待锁,当线程取锁失败就会使其进入系统的等待队列中
死锁在多道程序环境中,多个进程可以竞争有限数量的资源。当一个进程申请资源时,如果这时没有可用资源,那么这个进程进入等待状态。有时,如果所申请的资源被其他等待进程占有,那么该等待进程有可能再也无法改变状态。在代码中的体现为一个进程重复加锁。
守护进程概念
守护进程(Deamon)是运行在后台的一种特殊进程,是进程的一种。它在后台运行并且不受任何终端控制,独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件,常常在系统引导装入时启动,在系统关闭时停止。
代码
#include<stdio.h>
#include<pthread.h>
#define THRAD_NUM 2
pthread_mutex_t mutex;
int g_count = 0;
void* ThreadEntry(void* arg){
(void)arg;
int i;
for(i=0;i<10;i++){
//如果锁已经被其他线程获取到了,当线程在想获取,就会在lock 函数阻塞
pthread_mutex_lock(&mutex);//上锁
printf(" %d这是新线程输出\n",g_count);
g_count++;
pthread_mutex_unlock(&mutex); //开锁
}
return NULL;
}
int main(){
pthread_t tid[THRAD_NUM];//线程ID
pthread_mutex_init(&mutex,NULL);//互斥锁初始化
int i;
for(i=0;i<THRAD_NUM;i++) {
pthread_create(&tid[i], NULL, ThreadEntry, NULL);
}
for(i=0;i<10;i++){
printf("%d这是主线程输出\n",g_count);
g_count++;
}
for (i = 0; i < THRAD_NUM; ++i) { //释放新线程
pthread_join(tid[i], NULL);
}
printf("%d", g_count);
// pthread_mutex_destory(&mutex);//互斥锁释放函数 ????这个函数用不了我也不知道什么情况
return 0;
}
程序截图