C++ 之多线程简单教程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34719188/article/details/79946854

##· 多线程简介

多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。具有这种能力的系统包括对称多处理机、多核心处理器以及芯片级多处理(Chip-level multithreading)或同时多线程(Simultaneous multithreading)处理器。

软件多线程。即便处理器只能运行一个线程,操作系统也可以通过快速的在不同线程之间进行切换,由于时间间隔很小,来给用户造成一种多个线程同时运行的假象。这样的程序运行机制被称为软件多线程。如微软的Windows作业系统和Linux就是在各个不同的执行绪间来回切换,被称为单人多任务作业系统。而DOS这类文字接口作业系统在一个时间只能处理一项工作,被视为单人单工作业系统。

除此之外,许多系统及处理器也支持硬件多线程技术。对称多处理机(SMP)系统具有多个处理器,所以具有真正的同时执行多个线程的能力;CMP技术通过在一块芯片上集成多个核心(Core)也具有真正的多线程能力;CMT技术则稍有不同,有的是依靠硬件执行线程切换来获得多线程能力,操作系统不再负责线程切换,因而这部分开销可以减少甚至消除,这方面典型的例子是Sun的UltraSPARC T1,它同时综合了CMP和CMT。微软的Windows 2000以后的操作系统皆支持多线程与超线程技术。
[维基百科]


##· 子线程的实现

第一步:包含头文件

#include <Windows.h>  //调用的是系统API,不是C++自身语言的

第二步:在主函数新建线程对象

int main(void){

	···
	MyData threadData;  //定义需要传递给子线程的参数
	
	HANDLE hThread;  //线程名
	DWORD dwThreadID;  //线程句柄
	hThread = CreateThread(NULL,  //安全属性,一般设置为NULL
		0,   //默认堆栈大小,一般设置为 0 和 NULL
		ThreadProFunc1,  //线程执行函数,一些复杂耗时操作
		&threadData,  //线程携带的参数
		0, //0 代表创建后县成立吗执行,CREATE_SUSPEND 代表创建时候挂起
		&dwThreadID0);  //线程ID号,一般用于输出打印
	
	CloseHandle(hThread);  //等待线程结束后释放资源
	
	//ResumeThread(hThread);  //设置为 SUSPENG的线程开始执行函数
	
	···
	
	return 0;
}

第三步:声明并定义线程处理函数

/*
 * DWORD  固定写法
 * WINAPI  固定写法
 * ThreadProFunc 函数名,自己起
 * lpParameter  携带的参数
 */
DWORD WINAPI ThreadProFunc(LPVOID lpParameter){

	MyData * data = (MyData *)lpParameter;  //子线程收到参数
	
	//一些复杂的操作
	Sleep(10000);
	
	return 0;  //最后返回0
}

##· 多个子线程的执行及控制执行顺序

第一步:声明一个全局互斥锁

//定义互斥量
//互斥量,很好理解,就是单位时间内只能有一个线程使用的变量
//比如说银行卡存钱和取钱同时只能进行一项
HANDLE hMutex = NULL;  

第二步:定义两个子线程

int main(void){

	···

	//创建互斥锁
	/* 第一个参数,安全属性,一般设为 NULL
	 * 第二个参数,true代表当前线程(即主线程)拥有对hMutex 的所有权,主线程不释放,其他线程无法使用,作者就是在这里日了狗
	 * 第三个采纳数,给互斥量起一个名字,随意
	 */
	hMutex = CreateMutex(NULL,   
	false,  
	(LPCWSTR)"mMutex");  

	···

	HANDLE hThread[2];
	DWORD dwThreadID0, dwThreadID1;
	hThread[0] = CreateThread(NULL, 0, ThreadProFunc0, &data0, 0, NULL);
	hThread[1] = CreateThread(NULL, 0, ThreadProFunc1, &data1, 0, NULL);

	CloseHandle(hThread[0]);
	CloseHandle(hThread[1]);

	···

	return 0;

}

第三步:定义并实现线程处理函数

//线程函数0
DWORD WINAPI ThreadProFunc0(LPVOID lpParameter){

	//请求一个互斥量锁
	//hMutex  具体的互斥量
	//INFINITE 代表该线程等待无限时间,知道自己拥有 hMutex 的控制权
	//INFINITE 可以设置为具体的秒数,一旦等待时间达到指定秒数遍立马开始执行
	WaitForSingleObject(hMutex, INFINITE);

	//开始执行复杂耗时操作
	Sleep(10000);

	//执行完毕后,释放互斥量锁,方便其他函数调用
	ReleaseMutex(hMutex);

	retun 0;

}

//线程函数1
DWORD WINAPI ThreadProFunc0(LPVOID lpParameter){

	WaitForSingleObject(hMutex, INFINITE);
	Sleep(10000);
	ReleaseMutex(hMutex);

	retun 0;
}

这段代码实现了:
1、线程函数0和1不能同时执行
2、控制子线程执行的先后顺序的方法是 main 函数中创建的顺序

1、应当注意的是,子线程开始执行后,主线程如果没有其他限制条件的话,主线程还会继续执行,所以会出现主线程先结束,运行中的子线程因为主线程的结束而被迫结束!!!

2、应当注意的是,子线程开始执行后,主线程如果没有其他限制条件的话,主线程还会继续执行,所以会出现主线程先结束,运行中的子线程因为主线程的结束而被迫结束!!!

3、应当注意的是,子线程开始执行后,主线程如果没有其他限制条件的话,主线程还会继续执行,所以会出现主线程先结束,运行中的子线程因为主线程的结束而被迫结束!!!

重要的事情说三遍!!!


##· 总结

学生党,处理大数据,多线程是必不可少的!!!


##· 联系作者

邮箱:Neverland_LY@163.com

2018年4月15日 早

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页