计算机核心:CPU,承担了所有任务
计算机是由cpu+许多寄存器组成,memory是寄存器。在此基础上加上操作系统,在操作系统的基础上运行许多应用程序。
任务管理器:当前操作系统都运行了哪些应用程序。
操作系统:计算机管理者,负责:任务调度、资源分配、统领计算机硬件。程序在操作系统上运行。
关系:程序存储在电脑里,操作系统通过执行程序中的文件(exe),操作系统就将程序运行起来了,就变成了操作系统中的各个进程,程序加载至内存,一个程序可以有多个进程。
进程:进程是一个具有独立功能的程序,在一个数据集上的一次动态执行过程。
简言之:进程是跑起来的程序。
进程的性质:
每个进程都有一个pid号,多个相同程序的多个进程,pid小的是父进程。
进程间的切换,代价太大,无法满足需求,因此引入线程。
线程之间相互独立,但是例如内存空间、文件句柄、网络句柄,都是进程中的,是按照进程分配的,因此线程是共享的,线程切换不需要重新分配这些资源。
线程在任务切换中,是比进程快的,正是由于不需要切换资源。
三种执行方式:
并发是主要的多线程执行方式。
操作系统的任务调度采用的方式:时间片轮转的抢占式调用。
同时:让用户感觉是同时在执行,其实是几个任务切换着去执行,每执行一小部分就更换。
理论上,多核cpu可以实现并行,但是并发才是主要的执行方式,而且一般都是并发。
一个CPU同一时间只能执行一个任务,那么个所有要执行的任务,分配一个时间片,例如x秒,那么x秒之后,无论当前任务是否执行完毕,都会开始执行下一个任务。
并发:相同时间间隔交替执行。
线程是并发执行的,采用的是时间片轮转的抢占式调用。
调用函数之后返回线程句柄handle,用来操作线程的。句柄可以理解为id,对应唯一一个标识。
参数:
关于线程函数:表示线程要做的事情,而形参就是里面的一个单参数。
线程函数必须是一个参数,如果是多个参数,可以传入结构体。
最后的线程id,仅用来区分不同线程,而对线程的使用,是句柄的功能。
- DWORD WINAPI ThreadProc(LPVOID lpParameter){
- int count=(int)lpParameter;
- return 0;
- }
-
- CreateThread(0,0,&ThreadProc,(void*)80,0,0);
说明:
每次创建线程之后,系统就会在内部为线程分配一个内核对象,即一个thread对应一个内核对象。
内核对象作用:实现线程管理的函数
内核对象是什么:操作系统和线程的操作接口,实现了用户和操作系统的交互。
操作系统只管创建内核对象,但是不管回收,如果不回收,就会内存泄漏。
内置内核对象计数器,初始为0,创建线程+1,系统分配内核对象+1,也就是说,创建完线程之后就直接是2了。
线程执行完毕-1,手动关闭句柄-1,到此为0,完成了线程回收。
退出线程两步:
如果在流程中有死循环,先考虑用标志位退出。
- if(handle){
- isQuit=false;
- if(WAIT_TIMEOUT==WaitForSingleObject(handle,100);
- TerminateThread(handle,-1);
- }
- CloseHandle(handle);
- handle=0;
- }
首先要温和的退出,然后系统等待时间,如果超时了,就强制退出。
挂起=暂时不执行。
SuspendThread(handle);ResumeThread(handle);
有挂起计数器,挂起一次+1,恢复一次-1,0是最小的,不会再小了。