windows多线程没那么难

windows多线程没那么难

作者:vpoet

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

下面我又要介绍一个多线程的问题:
我们首先看一个Demo,经典的卖票问题,同一张牌不能卖出去两次:
复制代码
 1 #include <windows.h>
 2 #include <stdio.h>
 3 
 4 static int number=20;
 5 
 6 DWORD WINAPI ThreadOne(LPVOID lpParameter)
 7 {
 8     while(1)
 9     {
10         if(number>0)
11         {
12             printf("窗口1售出第%d张票...\n",number);
13             Sleep(1000);
14             number--;
15         }
16     }
17     return 0;
18 }
19 DWORD WINAPI ThreadTwo(LPVOID lpParameter)
20 {
21     while(1)
22     {
23         if(number>0)
24         {
25             printf("窗口2售出第%d张票...\n",number);
26             Sleep(1000);
27             number--;
28         }
29     }
30     return 0;
31 }
32 
33 
34 int main()
35 {
36     HANDLE HOne,HTwo;
37     printf("***********************vpoet******************\n");
38     HOne=CreateThread(NULL,0,ThreadOne,NULL,0,NULL);
39     printf("窗口1售票开始:\n");
40     HTwo=CreateThread(NULL,0,ThreadTwo,NULL,0,NULL);
41     printf("窗口2售票开始:\n");
42     CloseHandle(HOne);
43     CloseHandle(HTwo);
44     while(TRUE)
45     {
46         if(number==0)
47         {
48             printf("MainThread Over!\n");
49             return 0;
50         }
51         else
52         {
53             continue;
54         }    
55     }
56 
57     return 0;
58 }
复制代码

 

运行结果:


 
看到没,出现了同一张票卖两次的情况,这是绝对错误的,是违反能量守恒定律的。 这是为什么呢,因为我们对全局变量操作两个线程在同时进行,如果在窗口1线程的number++ 之前,窗口2线程取出了number这时的number还并未自加,所以出现了同一张票 卖两次的情况 那么我们就要用线程同步的方法来控制,怎么控制呢,在windows下控制 多线程同步一般有几种方法:临界区对象,事件对象和互斥对象以及锁 下面主要介绍临界区对象进行线程同步:



在win API中:
windows多线程没那么难_第1张图片

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



windows多线程没那么难_第2张图片
该函数等待指定的临界区对象的所有权,当获取指定的临界区对象的所有权之后该函数返回
其参数为临界区对象指针


windows多线程没那么难_第3张图片
该函数释放指定临界区对象的所有权,参数为临界区对象指针



windows多线程没那么难_第4张图片
该函数为删除释放临界区对象资源






那么接下来我们将用临界区对程序进行改写:
复制代码
 1 #include <windows.h>
 2 #include <stdio.h>
 3 
 4 static int number=10;
 5 CRITICAL_SECTION Section;
 6 
 7 DWORD WINAPI ThreadOne(LPVOID lpParameter)
 8 {
 9     while(1)
10     {
11         EnterCriticalSection(&Section);
12         if(number>0)
13         {
14             printf("窗口1售出第%d张票...\n",number);
15             number--;
16             Sleep(1000);        
17         }
18         LeaveCriticalSection(&Section);
19     }
20     return 0;
21 }
22 DWORD WINAPI ThreadTwo(LPVOID lpParameter)
23 {
24     while(1)
25     {
26         EnterCriticalSection(&Section);
27         if(number>0)
28         {
29             printf("窗口2售出第%d张票...\n",number);
30             Sleep(1000);
31             number--;
32         }
33         LeaveCriticalSection(&Section);
34     }
35     return 0;
36 }
37 
38 
39 int main()
40 {
41     HANDLE HOne,HTwo;
42     InitializeCriticalSection(&Section);
43     printf("***********************vpoet******************\n");
44     HOne=CreateThread(NULL,0,ThreadOne,NULL,0,NULL);
45     printf("窗口1售票开始:\n");
46     HTwo=CreateThread(NULL,0,ThreadTwo,NULL,0,NULL);
47     printf("窗口2售票开始:\n");
48     CloseHandle(HOne);
49     CloseHandle(HTwo);
50     while(TRUE)
51     {
52         if(number==0)
53         {
54             printf("不好意思,票卖完了!\n");
55             DeleteCriticalSection(&Section);
56             return 0;
57         }
58         else
59         {
60             continue;
61         }    
62     }
63 
64     return 0;
65 }
复制代码
运行结果如下:

这下票卖对了吧。

好了,Only stop here!
下面的博文我将介绍其他几种线程同步的方法。
windows多线程没那么难_第5张图片

你可能感兴趣的:(多线程,windows)