门头沟网站建设公司,军博网站建设,wordpress主题制作函数完整版,深圳做网站公司排名c qt–线程#xff08;一#xff09;#xff08;第八部分#xff09;
一.进程#xff08;Process#xff09;
在任务管理器中的进程页下#xff0c;可以看到进程#xff0c;任务管理器将进程分为了三类#xff0c;应用、后台进程、window进程 应用#xff1a;
打开…c qt–线程一第八部分
一.进程Process
在任务管理器中的进程页下可以看到进程任务管理器将进程分为了三类应用、后台进程、window进程 应用
打开的正在运行的软件
后台进程
隐藏在后台“悄悄”的运行
window进程
操作系统启动、运行需要依赖的各种服务
1.进程的概念
是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程是操作系统进行资源分配和调度的一个独立的基本单元是应用程序运行的载体
进程是一种抽象的概念从来没有统一的标准定义
2.进程的组成
进程由程序、数据集合、进程控制块三部分组成
3.进程的4个特征
1.动态性进程是程序的一次执行过程是临时的有生命期的是动态产生。动态消亡的
2.并发性任何进程都可以同其他进程一起并发执行
3.独立性进程是程序进行资源分配和调度的一个独立单元
4.结构性进程由程序、数据集合、进程控制块三部分组成
4.应用程序和进程间的关系
一个应用程序下的多个进程是树形结构。
PID是进程的唯一标识符PID最小的数是根节点
二.线程Thread
1.线程的概念
cpu能够进行调度、分配、执行、运算的最小的基本单位。是程序执行中一个单一的顺序控制流程一个进程可以有一个或多个线程各个线程之间共享进程的内存空间
2.线程的串行并行和并发
串行按照顺序。一个执行完再执行下一个
并行同一个时刻同时进行
并发再同一个时间间隔内发生指相同的时间间隔交替执行
在单线程下采用串行的方式执行
大部分操作系统的任务调度是采用轮换时间片的抢占式调度方式一个线程执行一小段时间后暂停休息并等待着被唤醒下一个线程被唤醒并开始执行每个线程交替轮流执行。线程执行的一小段时间叫做时间片
由于cpu的执行速度非常快时间片非常短在各个线程之间快速地切换给人的感觉就是多个线程在“同时进行”这就是常说的并发
3.线程的状态
1.新生态创建出新的线程对象
2.就绪态创建出线程后进入就绪态会将线程添加到就绪队列中等待分配到cpu时间片就会进行运行状态
3.运行态运行态的线程如果时间片用完后就会再次进入就绪状态一般来说就绪态和运行态不需要认为参与由操作系统进行调度如果遇到sleep、wait、suspend、IO请求时就会进入阻塞态
4.阻塞态挂起状态一个正在运行的线程在某些特殊情况下如被认为挂起或执行好事的I/O操作时会让出cpu的使用权并暂时中止自己的执行进入阻塞状态处于阻塞状态的线程就不能进入排队队列。只有当引起阻塞的原因被消除后线程才可以转入就绪状态。当恢复线程完成IO操作、等到资源就会进入就绪状态
5.销亡态线程正常执行结束、因异常退出、被强制终止该线程结束生命周期
注意
1.线程必须通过就绪态分配到时间片才能进入运行状态而不能直接进入运行状态
2.就绪状态无法进入阻塞状态
3.其他状态的线程可直接进入销亡态
三.使用QT创建线程进一步理解线程
1.创建一个控制台窗口 2.创建线程
1.使用的头文件为
#include windows.h2.创建线程
在main.cpp中的mian函数中写下面代码
int n20;
//创建一个子线程主线程可以看作是main函数 的执行
HANDLE handle::CreateThread(nullptr/*使用默认的安全属性*/,//线程的安全属性返回的是线程句柄这里我们用线程句柄接一下0//用默认的线程栈大小window1M,ThreadProc//线程函数,n//线程函数传递的参数,0//创建线程后0:立即执行,CREATE_SUSPENDED:挂起,nullptr//返回线程ID);
3.线程函数
在main.cpp中写下面代码
DWORD (WINAPI/*调用约定*/ ThreadProc) (LPVOID/* void* */ lpThreadParameter){return 0;//表示当前函数正常退出
}4.通过输出观察两个线程的执行
主线程
int n20;
//创建一个子线程主线程可以看作是main函数 的执行
HANDLE handle::CreateThread(nullptr/*使用默认的安全属性*/,//线程的安全属性返回的是线程句柄这里我们用线程句柄接一下0//用默认的线程栈大小window1M,ThreadProc//线程函数,n//线程函数传递的参数,0//创建线程后0:立即执行,CREATE_SUSPENDED:挂起,nullptr//返回线程ID);//进行一个输入看主线程与子线程的关系
for(int i0;i20;i){qDebug()--------------------------------主人 睡了i;Sleep(1000);
}子线程
DWORD (WINAPI/*调用约定*/ ThreadProc) (LPVOID/* void* */ lpThreadParameter){//进行一个输入看主线程与子线程的关系int n*(int*)lpThreadParameter;//将void*强转为int*最后取其中的值for(int i0;in;i){qDebug()仆人在挣钱i;Sleep(1000);}return 0;//表示当前函数正常退出
}5.线程的挂起、恢复操作这里对子线程挂起和恢复操作
主线程
在main.cpp中的mian函数中写下面代码
int n20;HANDLE handle::CreateThread(nullptr,0,ThreadProc,n/,CREATE_SUSPENDED//这里改为了CREATE_SUSPENDED挂起,nullptr);for(int i0;i20;i){if(i3){//返回的是恢复或挂起之前 挂起计数器的值当挂起计数器的值为0时线程才能继续运行//挂起几次就得恢复几次线程才能继续运行DWORD count::ResumeThread(handle);//恢复某一个线程运行qDebug()count111 count;}if(i7){DWORD count::SuspendThread(handle);qDebug()count222 count;}if(i10){DWORD count::SuspendThread(handle);qDebug()count333 count;}if(i13){DWORD count::ResumeThread(handle);qDebug()count444 count;}if(i15){DWORD count::ResumeThread(handle);qDebug()count555 count;}qDebug()--------------------------------主人 睡了i;Sleep(1000);
}子线程
在main.cpp中写下面代码
DWORD (WINAPI/*调用约定*/ ThreadProc) (LPVOID/* void* */ lpThreadParameter){//进行一个输入看主线程与子线程的关系int n*(int*)lpThreadParameter;//将void*强转为int*最后取其中的值for(int i0;in;i){qDebug()仆人在挣钱i;Sleep(1000);}return 0;//表示当前函数正常退出
}6.线程的关闭和退出操作
定义两个关于退出标志
bool isTreadQuitfalse;//退出的标志这里初始是不退出
bool isAlreadyQuitfalse;//告诉主线程退出了这里初始是不告诉主线程
在main.cpp中的mian函数中写下面代码
int n20;//创建第一个线程时也会创建内核对象这时使用计数默认1
HANDLE handle::CreateThread(nullptr,0,ThreadProc,n/,0//这里改为了0立即执行,nullptr);for(int i0;i20;i){qDebug()--------------------------------主人 睡了i;if(i6){isTreadQuittrue;qDebug()通知子线程退出;break;}//第一种 一直等子线程退出的标记//while(1){// if(isAlreadyQuit){// qDebug()收到子线程退出的标记了;// break;// }// Sleep(1000);//}//第二种设置等待时间等子线程退出这里设置的是7秒DWORD flagWaitForSingleObject(handle,7000);//这里的参数单位是毫秒if(flagWAIT_OBJECT_0){//在设定的等待时间内子线程正常退出了qDebug()子线程退出了;}else if(flagWAIT_TIMEOUT){//在设定的等待时间内子线程没有退出等待超时了qDebug()等待超时强制杀死线程;::TerminateThread(handle,-1);//强制杀死子线程,有风险的方式}if(handle){::CloseHandle(handle);//关闭句柄使用计数-1当使用计数减为0的时候系统就会回收内核对象·}handlenullptr;Sleep(1000);
}子线程
在main.cpp中写下面代码
DWORD (WINAPI/*调用约定*/ ThreadProc) (LPVOID/* void* */ lpThreadParameter){int n*(int*)lpThreadParameter;while(!isTreadQuit){qDebug()仆人在挣钱;Sleep(1000);}//第一种//isAlreadyQuittrue;return 0;
}