win32 多线程编程

Posted 不会写代码的丝丽

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了win32 多线程编程相关的知识,希望对你有一定的参考价值。


#include <iostream>
#include <Windows.h>
#include<tlhelp32.h>
using namespace std;
#include <string> 



DWORD WINAPI myRun(
	_In_ LPVOID lpParameter
) {

	cout << "子线程的第一个信息" << endl;
	Sleep(200);
	cout << "子线程的第二个信息" << endl;

	//可以自行强制调用这个函数退出
	//while (true)
	//{
		//ExitThread(0);
	//}


	
	//退出代码
	return EXIT_SUCCESS;
}

int main()
{

	DWORD threadId;

	HANDLE threadHandle = CreateThread(NULL,//是否返回的句柄能让子进程继承
		0,//设置线程栈大小。越小递归深度越深,但是栈帧内存越小,0是默认设置
		myRun,//方法指针,线程运行时会调用这个函数
		NULL,//可传入任意的指针给线程参数
		CREATE_SUSPENDED,//线程启动参数,传入0线程创建时立即运行。CREATE_SUSPENDED会在ResumeThread 才运行
		&threadId//传出 线程id
	);

	cout << "主线程准备让子线程运行" << endl;
	//由于创建指定了CREATE_SUSPENDED所以必须在ResumeThread才运行
	ResumeThread(threadHandle);
	
	//给子线程打印的机会
	Sleep(100);

	cout << "主线程准备挂起线程" << endl;
	//挂起线程
	SuspendThread(threadHandle);

	//给子线程打印的机会
	Sleep(500);
	cout << "主线程恢复子线程运行" << endl;
	//恢复线程
	ResumeThread(threadHandle);

	

	//强制退出某个线程,注意资源释放问题
	//TerminateThread(threadHandle,0);

	//等候线程结束
	WaitForSingleObject(threadHandle, INFINITE);


	DWORD exitCode;
	GetExitCodeThread(threadHandle,&exitCode);

	cout << "子线程退出code " << exitCode << endl;
	
	CloseHandle(threadHandle);


	return EXIT_SUCCESS;

}

在这里插入图片描述

多线程同步问题

下面有一个小实验:两个线程对同一共享变量进行各自自增100000次,最后的结果预测的情况应该是200000

//共享变量
int i = 0;
//多个线程同时运行函数
DWORD WINAPI myRun(	_In_ LPVOID lpParameter) {
	
	for (size_t j = 0; j < 100000; j++){
		++::i;
	}

	//退出代码
	return EXIT_SUCCESS;
}

int main()
{
	
	DWORD threadId;

	HANDLE threadHandle = CreateThread(NULL,//是否返回的句柄能让子进程继承
		0,//设置线程栈大小。越小递归深度越深,但是栈帧内存越小,0是默认设置
		myRun,//方法指针,线程运行时会调用这个函数
		NULL,//可传入任意的指针给线程参数
		CREATE_SUSPENDED,//线程启动参数,传入0线程创建时立即运行。CREATE_SUSPENDED会在ResumeThread 才运行
		&threadId//传出 线程id
	);

	ResumeThread(threadHandle);
	DWORD threadId2;

	HANDLE threadHandle2 = CreateThread(NULL,//是否返回的句柄能让子进程继承
		0,//设置线程栈大小。越小递归深度越深,但是栈帧内存越小,0是默认设置
		myRun,//方法指针,线程运行时会调用这个函数
		NULL,//可传入任意的指针给线程参数
		CREATE_SUSPENDED,//线程启动参数,传入0线程创建时立即运行。CREATE_SUSPENDED会在ResumeThread 才运行
		&threadId2//传出 线程id
	);


	ResumeThread(threadHandle2);


	//等候线程结束
	WaitForSingleObject(threadHandle, INFINITE);
	WaitForSingleObject(threadHandle2, INFINITE);

	cout<<"cur "<<i<<endl;
	
	
	CloseHandle(threadHandle);
	CloseHandle(threadHandle2);


	return EXIT_SUCCESS;

}

在这里插入图片描述

对于这个现象网上有很多解释大家可以自己自行查阅 原子性相关文献。
对于自增的共享变量我们可以采用win32提供原子性操作API:
列表如下:
在这里插入图片描述
我们将代码修改如下

int i = 0;
DWORD WINAPI myRun(
	_In_ LPVOID lpParameter
) {

	
	for (size_t j = 0; j < 100000; j++)
	{
		//保证i操作是原子性的自增
		InterlockedIncrement((unsigned int *)&i);
	}

	//退出代码
	return EXIT_SUCCESS;
}

在这里插入图片描述

当然对于复杂的情况我们也可以使用临界区函数:

lude <string> 

//临界区
CRITICAL_SECTION cs;
int i = 0;
DWORD WINAPI myRun(
	_In_ LPVOID lpParameter
) {

	
	for (size_t j = 0; j < 100000; j++)
	{
		//仅有一个线程能进入临界区
		EnterCriticalSection(&cs);
		++::i;
		//InterlockedIncrement((unsigned int *)&i);
		LeaveCriticalSection(&cs);
	}

	//退出代码
	return EXIT_SUCCESS;
}


int main()
{
	
	//初始化临界区
	InitializeCriticalSection(&cs);
	//...略
	//回收临界区资源
	DeleteCriticalSection(&cs);


	return EXIT_SUCCESS;

}


以上是关于win32 多线程编程的主要内容,如果未能解决你的问题,请参考以下文章

Win32 多线程编程

win32 多线程编程

win32 多线程编程

Win32多线程

Win32多线程调用gdal库接口

win32编程简介