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张票...\n",number); Sleep(1000); number--; } } return 0; } DWORD WINAPI ThreadTwo(LPVOID lpParameter) { while(1) { if(number>0) { printf("窗体2售出第%d张票...\n",number); Sleep(1000); number--; } } return 0; } int main() { HANDLE HOne,HTwo; printf("***********************vpoet******************\n"); HOne=CreateThread(NULL,0,ThreadOne,NULL,0,NULL); printf("窗体1售票開始:\n"); HTwo=CreateThread(NULL,0,ThreadTwo,NULL,0,NULL); printf("窗体2售票開始:\n"); CloseHandle(HOne); CloseHandle(HTwo); while(TRUE) { if(number==0) { printf("MainThread Over!\n"); 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张票...\n",number); number--; Sleep(1000); } LeaveCriticalSection(&Section); } return 0; } DWORD WINAPI ThreadTwo(LPVOID lpParameter) { while(1) { EnterCriticalSection(&Section); if(number>0) { printf("窗体2售出第%d张票...\n",number); Sleep(1000); number--; } LeaveCriticalSection(&Section); } return 0; } int main() { HANDLE HOne,HTwo; InitializeCriticalSection(&Section); printf("***********************vpoet******************\n"); HOne=CreateThread(NULL,0,ThreadOne,NULL,0,NULL); printf("窗体1售票開始:\n"); HTwo=CreateThread(NULL,0,ThreadTwo,NULL,0,NULL); printf("窗体2售票開始:\n"); CloseHandle(HOne); CloseHandle(HTwo); while(TRUE) { if(number==0) { printf("不好意思,票卖完了!\n"); DeleteCriticalSection(&Section); return 0; } else { continue; } } return 0; }执行结果例如以下:
这下票卖对了吧。
好了,Only stop here!
以下的博文我将介绍其它几种线程同步的方法。