windows多线程没那么难

windows多线程没那么难

作者:vpoet
mail:vpoet_sir@163.com

上一博文中我们引入了CreateThread()多线程编程一个简单的样例,其实我说windows
多线程没那么难,那是为了安慰你,可是不要怕,困难时让人克服的。

再大的困难也难不

倒英雄的中国程序猿。

以下我又要介绍一个多线程的问题:
我们首先看一个Demo,经典的卖票问题,同一张牌不能卖出去两次:

#include <windows.h>
#include <stdio.h>

static int number=20;

DWORD WINAPI ThreadOne(LPVOID lpParameter)
{
	while(1)
	{
		if(number>0)
		{
			printf("窗体1售出第%d张票...
",number);
			Sleep(1000);
			number--;
		}
	}
	return 0;
}
DWORD WINAPI ThreadTwo(LPVOID lpParameter)
{
	while(1)
	{
		if(number>0)
		{
			printf("窗体2售出第%d张票...
",number);
			Sleep(1000);
			number--;
		}
	}
	return 0;
}


int main()
{
	HANDLE HOne,HTwo;
	printf("***********************vpoet******************
");
	HOne=CreateThread(NULL,0,ThreadOne,NULL,0,NULL);
	printf("窗体1售票開始:
");
	HTwo=CreateThread(NULL,0,ThreadTwo,NULL,0,NULL);
	printf("窗体2售票開始:
");
	CloseHandle(HOne);
	CloseHandle(HTwo);
	while(TRUE)
	{
		if(number==0)
		{
			printf("MainThread Over!
");
			return 0;
		}
		else
		{
			continue;
		}	
	}

	return 0;
}
执行结果:


看到没,出现了同一张票卖两次的情况,这是绝对错误的。是违反能量守恒定律的。
这是为什么呢。由于我们对全局变量操作两个线程在同一时候进行,假设在窗体1线程的number++
之前,窗体2线程取出了number这时的number还并未自加,所以出现了同一张票
卖两次的情况

那么我们就要用线程同步的方法来控制,怎么控制呢,在windows下控制
多线程同步一般有几种方法:临界区对象,事件对象和相互排斥对象以及锁
以下主要介绍临界区对象进行线程同步:



在win API中:


该函数为初始化临界区函数,參数为临界区对象




该函数等待指定的临界区对象的全部权,当获取指定的临界区对象的全部权之后该函数返回
其參数为临界区对象指针



该函数释放指定临界区对象的全部权,參数为临界区对象指针




该函数为删除释放临界区对象资源






那么接下来我们将用临界区对程序进行改写:
#include <windows.h>
#include <stdio.h>

static int number=10;
CRITICAL_SECTION Section;

DWORD WINAPI ThreadOne(LPVOID lpParameter)
{
	while(1)
	{
		EnterCriticalSection(&Section);
		if(number>0)
		{
			printf("窗体1售出第%d张票...
",number);
			number--;
			Sleep(1000);		
		}
		LeaveCriticalSection(&Section);
	}
	return 0;
}
DWORD WINAPI ThreadTwo(LPVOID lpParameter)
{
	while(1)
	{
		EnterCriticalSection(&Section);
		if(number>0)
		{
			printf("窗体2售出第%d张票...
",number);
			Sleep(1000);
			number--;
		}
		LeaveCriticalSection(&Section);
	}
	return 0;
}


int main()
{
	HANDLE HOne,HTwo;
	InitializeCriticalSection(&Section);
	printf("***********************vpoet******************
");
	HOne=CreateThread(NULL,0,ThreadOne,NULL,0,NULL);
	printf("窗体1售票開始:
");
	HTwo=CreateThread(NULL,0,ThreadTwo,NULL,0,NULL);
	printf("窗体2售票開始:
");
	CloseHandle(HOne);
	CloseHandle(HTwo);
	while(TRUE)
	{
		if(number==0)
		{
			printf("不好意思,票卖完了!
");
			DeleteCriticalSection(&Section);
			return 0;
		}
		else
		{
			continue;
		}	
	}

	return 0;
}
执行结果例如以下:


这下票卖对了吧。


好了,Only stop here!
以下的博文我将介绍其它几种线程同步的方法。
原文地址:https://www.cnblogs.com/claireyuancy/p/6895012.html