【操作系统】线程

计算机组成

计算机核心:CPU,承担了所有任务

计算机是由cpu+许多寄存器组成,memory是寄存器。在此基础上加上操作系统,在操作系统的基础上运行许多应用程序。

任务管理器:当前操作系统都运行了哪些应用程序。

  • 应用:正在使用的程序
  • 后台:一般是看不到的,例如flash或者是硬件驱动
  • windows进程:操作系统启动时需要依赖的各种服务

操作系统:计算机管理者,负责:任务调度、资源分配、统领计算机硬件。程序在操作系统上运行。

进程

关系:程序存储在电脑里,操作系统通过执行程序中的文件(exe),操作系统就将程序运行起来了,就变成了操作系统中的各个进程,程序加载至内存,一个程序可以有多个进程。

进程:进程是一个具有独立功能的程序,在一个数据集上的一次动态执行过程。

简言之:进程是跑起来的程序。

进程的性质:

  1. 动态性:进程是程序的一次执行过程,临时的,有生命周期的,动态产生,动态消亡
  2. 并发性:任何进程都可以同其他进程一起并发执行
  3. 独立性:进程是系统进行资源分配和调度的一个独立单位
  4. 结构性:进程由程序、数据集合、进程控制块(PCB)三部分组成

每个进程都有一个pid号,多个相同程序的多个进程,pid小的是父进程。

  • 进程process:系统分配资源的基本单元
  • 线程thread:cpu调度和执行的基本单元

为什么引入线程?

进程间的切换,代价太大,无法满足需求,因此引入线程。

线程之间相互独立,但是例如内存空间、文件句柄、网络句柄,都是进程中的,是按照进程分配的,因此线程是共享的,线程切换不需要重新分配这些资源。

线程在任务切换中,是比进程快的,正是由于不需要切换资源。

为什么要使用线程?

  1. 更快的完成任务
  2. 当一些需要同时操作的场景,例如下载的同时聊天,使其互不影响

多个线程如何执行的?

三种执行方式:

  • 串行:按顺序执行
  • 并行:同一时间一起,例如赛跑
  • 并发:单核CPU无法并行,一个CPU在同一时间只能完成一个任务,但是多核就可以

并发是主要的多线程执行方式。

操作系统的任务调度采用的方式:时间片轮转的抢占式调用。

同时:让用户感觉是同时在执行,其实是几个任务切换着去执行,每执行一小部分就更换。

理论上,多核cpu可以实现并行,但是并发才是主要的执行方式,而且一般都是并发。

一个CPU同一时间只能执行一个任务,那么个所有要执行的任务,分配一个时间片,例如x秒,那么x秒之后,无论当前任务是否执行完毕,都会开始执行下一个任务。

并发:相同时间间隔交替执行。

线程是并发执行的,采用的是时间片轮转的抢占式调用。

CreateThread函数

调用函数之后返回线程句柄handle,用来操作线程的。句柄可以理解为id,对应唯一一个标识。

参数:

  1. 安全描述符:一般是NULL
  2. 栈大小:一般是0,标识默认大小1mb
  3. 线程函数地址:标识函数的功能
  4. 线程函数形参:函数的参数
  5. 创建线程的初始状态:0表示创建后立刻执行,CREATE_SUSPENDED创建后立刻挂起
  6. 线程id:一般是NULL

关于线程函数:表示线程要做的事情,而形参就是里面的一个单参数。

线程函数必须是一个参数,如果是多个参数,可以传入结构体。

最后的线程id,仅用来区分不同线程,而对线程的使用,是句柄的功能。

DWORD WINAPI ThreadProc(LPVOID lpParameter){
    int count=(int)lpParameter;
    return 0;
}

CreateThread(0,0,&ThreadProc,(void*)80,0,0);

说明:

  • DWORD表示双字节数据类型,可以理解为unsigned int
  • WINAPI是windows调用约定,仅windows可以用
  • LPVOID和void*是一回事
  • 在函数中必须有形参类型转换

内核对象

每次创建线程之后,系统就会在内部为线程分配一个内核对象,即一个thread对应一个内核对象。

内核对象作用:实现线程管理的函数

内核对象是什么:操作系统和线程的操作接口,实现了用户和操作系统的交互。

操作系统只管创建内核对象,但是不管回收,如果不回收,就会内存泄漏。

操作系统回收内核对象过程

内置内核对象计数器,初始为0,创建线程+1,系统分配内核对象+1,也就是说,创建完线程之后就直接是2了。

线程执行完毕-1,手动关闭句柄-1,到此为0,完成了线程回收。

退出线程两步:

  1. 线程执行结束,有些时候并不能自行结束,需要人工,例如bool的标志位,或者等待或者强制
  2. CloseHandle

如果在流程中有死循环,先考虑用标志位退出。

if(handle){
    isQuit=false;
    if(WAIT_TIMEOUT==WaitForSingleObject(handle,100);
        TerminateThread(handle,-1);
    }
    CloseHandle(handle);
    handle=0;
}

首先要温和的退出,然后系统等待时间,如果超时了,就强制退出。

挂起=暂时不执行。

SuspendThread(handle);ResumeThread(handle);

有挂起计数器,挂起一次+1,恢复一次-1,0是最小的,不会再小了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值