码迷,mamicode.com
首页 > 编程语言 > 详细

WinApi多线程(CreateThread,CreateMutex,ReleaseMutex)

时间:2015-05-16 23:18:45      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:

注:本文写得十分简略.如感到难以理解,请立即参考另一篇写得比我好得多的文章

我们先看一个示例

 1 #include <windows.h>
 2 #include <stdio.h>
 3 
 4 DWORD WINAPI reportFunc(LPVOID); // 线程函数的一般原型.可以不返回任何值
 5 
 6 #define CntMsg 100
 7 
 8 int main()
 9 {
10   /* 建立一个新线程并令其立即执行,返回这个线程的handle
11    * 第三个参数reportFunc代表这个新线程所调用的函数,不同线程可以调用同一个函数
12    * 第四个参数NULL代表传给reportFunc的参数(建议使用指针).传参时会转成void指针,由接收方再转成需要的类型.将会在下个示例程序中用到
13    * 第五个参数0代表立即执行此线程
14    */
15   HANDLE reportHandle = CreateThread(NULL, 0, reportFunc, NULL, 0, NULL);
16   CloseHandle(reportHandle); // 礼节性调用.可有可无
17   
18   for (int i = 0; i < CntMsg; ++i) printf("Main Thread: %d\n", i);
19   
20   Sleep(1000); // 如果不加这一句,可能会造成主线程报完数并退出后子线程尚未报完数的情况 
21 }
22 
23 DWORD WINAPI reportFunc(LPVOID para)
24 {
25   for (int i = 0; i < CntMsg; ++i) printf("Report Thread: %d\n", i);
26 }

它的输出大概是这样的(不知道是因为什么,我前两次测试的结果都很奇怪:主线程报完数后子线程才开始报数.这是我第三次测试的结果)

技术分享
Main Thread: 0
Main Thread: 1
Main Thread: 2
Main Thread: 3
Main Thread: 4
Main Thread: 5
Main Thread: 6
Main Thread: 7
Main Thread: 8
Main Thread: 9
Main Thread: 10
Main Thread: 11
Main Thread: 12
Main Thread: 13
Main Thread: 14
Main Thread: 15
Main Thread: 16
Main Thread: 17
Main Thread: 18
Main Thread: 19
Main Thread: 20
Main Thread: 21
Main Thread: 22
Main Thread: 23
Main Thread: 24
Main Thread: 25
Main Thread: 26
Main Thread: 27
Main Thread: 28
Main Thread: 29
Main Thread: 30
Main Thread: 31
Main Thread: 32
Main Thread: 33
Main Thread: 34
Main Thread: 35
Main Thread: 36
Main Thread: 37
Main Thread: 38
Main Thread: 39
Main Thread: 40
Main Thread: 41
Main Thread: 42
Main Thread: 43
Main Thread: 44
Main Thread: 45
Main Thread: 46
Main Thread: 47
Main Thread: 48
Main Thread: 49
Main Thread: 50
Main Thread: 51
Main Thread: 52
Main Thread: 53
Report Thread: 0
Report Thread: 1
Report Thread: 2
Report Thread: 3
Report Thread: 4
Report Thread: 5
Report Thread: 6
Report Thread: 7
Report Thread: 8
Report Thread: 9
Report Thread: 10
Report Thread: 11
Report Thread: 12
Report Thread: 13
Report Thread: 14
Report Thread: 15
Report Thread: 16
Report Thread: 17
Report Thread: 18
Report Thread: 19
Report Thread: 20
Report Thread: 21
Report Thread: 22
Report Thread: 23
Report Thread: 24
Report Thread: 25
Report Thread: 26
Report Thread: 27
Report Thread: 28
Report Thread: 29
Report Thread: 30
Report Thread: 31
Report Thread: 32
Report Thread: 33
Report Thread: 34
Report Thread: 35
Report Thread: 36
Report Thread: 37
Report Thread: 38
Report Thread: 39
Report Thread: 40
Report Thread: 41
Report Thread: 42
Report Thread: 43
Report Thread: 44
Report Thread: 45
Report Thread: 46
Report Thread: 47
Report Thread: 48
Main Thread: 54
Main Thread: 55
Main Thread: 56
Main Thread: 57
Main Thread: 58
Main Thread: 59
Main Thread: 60
Main Thread: 61
Main Thread: 62
Main Thread: 63
Main Thread: 64
Main Thread: 65
Main Thread: 66
Main Thread: 67
Main Thread: 68
Main Thread: 69
Main Thread: 70
Main Thread: 71
Main Thread: 72
Main Thread: 73
Main Thread: 74
Main Thread: 75
Main Thread: 76
Main Thread: 77
Main Thread: 78
Main Thread: 79
Main Thread: 80
Main Thread: 81
Main Thread: 82
Main Thread: 83
Main Thread: 84
Main Thread: 85
Main Thread: 86
Main Thread: 87
Main Thread: 88
Main Thread: 89
Main Thread: 90
Main Thread: 91
Main Thread: 92
Main Thread: 93
Main Thread: 94
Main Thread: 95
Main Thread: 96
Main Thread: 97
Main Thread: 98
Main Thread: 99
Report Thread: 49
Report Thread: 50
Report Thread: 51
Report Thread: 52
Report Thread: 53
Report Thread: 54
Report Thread: 55
Report Thread: 56
Report Thread: 57
Report Thread: 58
Report Thread: 59
Report Thread: 60
Report Thread: 61
Report Thread: 62
Report Thread: 63
Report Thread: 64
Report Thread: 65
Report Thread: 66
Report Thread: 67
Report Thread: 68
Report Thread: 69
Report Thread: 70
Report Thread: 71
Report Thread: 72
Report Thread: 73
Report Thread: 74
Report Thread: 75
Report Thread: 76
Report Thread: 77
Report Thread: 78
Report Thread: 79
Report Thread: 80
Report Thread: 81
Report Thread: 82
Report Thread: 83
Report Thread: 84
Report Thread: 85
Report Thread: 86
Report Thread: 87
Report Thread: 88
Report Thread: 89
Report Thread: 90
Report Thread: 91
Report Thread: 92
Report Thread: 93
Report Thread: 94
Report Thread: 95
Report Thread: 96
Report Thread: 97
Report Thread: 98
Report Thread: 99
View Code

这个程序的功能是建立一个新线程,令其与主线程一起报数

几个线程同时访问同一个变量时,可能会出现一些问题.为了解决这个问题,有人发明了Mutex.这是一个标志,用于判断某个东东是否无法在现在访问(即现在正在被其它线程访问)

下面我们看看第二个示例程序

 1 #include <windows.h>
 2 #include <stdio.h>
 3 
 4 int tickets = 100; // 票量 
 5 HANDLE ticketMutex; // Mutex的类型是HANDLE 
 6 
 7 DWORD WINAPI trainStation(LPVOID para)
 8 {
 9   char* stationName = para; // 转类型,接收车站名信息 
10   
11   while (1)
12   {
13       // 等待Mutex被其它线程释放后,锁定Mutex
14     // 锁定Mutex,相当于告诉其它线程要等待它调用ReleaseMutex后,才能对tickets变量进行操作 
15     WaitForSingleObject(ticketMutex, INFINITE);
16     
17     if (tickets <= 0) break;
18     printf("%s> %d\n", stationName, --tickets); // 抢票 
19     
20     // 释放Mutex,告诉其它线程可以开始对tickets变量进行操作了 
21     ReleaseMutex(ticketMutex);
22   }
23 }
24 
25 #define ARRSIZ(arr) (sizeof(arr) / sizeof(arr[0]))
26 
27 int main()
28 {
29   // 使用CreateMutex函数来建立一个Mutex
30   // 其中,最后一个(第三个)参数是一个标识符
31   // 假如需要判断此Mutex是否已被创建,可以写类似CreateMutex(NULL, FALSE, "tickets")之类的代码
32   // 如果另一个标识符为"tickets"的Mutex已被创建,那么ERROR_ALREADY_EXISTS == GetLastError()
33   ticketMutex = CreateMutex(NULL, FALSE, NULL);
34 
35   // 车站名 
36   char stations[][20] =
37     {
38       "GuangZhou", "BeiJing", "ShangHai",
39       "HuNan", "HeiLongJiang", "XinJiang",
40     };
41   
42   // 依次创建代表各省车站的子线程 
43   for (int i = 0; i < ARRSIZ(stations); ++i)
44   {
45     CloseHandle(CreateThread(NULL, 0, trainStation, stations[i], 0, NULL));
46   }
47   
48   while (1)
49   {
50     WaitForSingleObject(ticketMutex, INFINITE); // 同上 
51     if (tickets <= 0) break; // 假如票卖完了,退出程序 
52     ReleaseMutex(ticketMutex); // 同上 
53   }
54 }

 

它的输出大概是这样的

技术分享
GuangZhou> 99
GuangZhou> 98
GuangZhou> 97
GuangZhou> 96
GuangZhou> 95
ShangHai> 94
GuangZhou> 93
ShangHai> 92
GuangZhou> 91
HeiLongJiang> 90
HuNan> 89
ShangHai> 88
BeiJing> 87
XinJiang> 86
GuangZhou> 85
HeiLongJiang> 84
HuNan> 83
ShangHai> 82
BeiJing> 81
XinJiang> 80
GuangZhou> 79
HeiLongJiang> 78
HuNan> 77
ShangHai> 76
BeiJing> 75
XinJiang> 74
GuangZhou> 73
HeiLongJiang> 72
HuNan> 71
ShangHai> 70
BeiJing> 69
XinJiang> 68
GuangZhou> 67
HeiLongJiang> 66
HuNan> 65
ShangHai> 64
BeiJing> 63
XinJiang> 62
GuangZhou> 61
HeiLongJiang> 60
HuNan> 59
ShangHai> 58
BeiJing> 57
XinJiang> 56
GuangZhou> 55
HeiLongJiang> 54
HuNan> 53
ShangHai> 52
BeiJing> 51
XinJiang> 50
GuangZhou> 49
HeiLongJiang> 48
HuNan> 47
ShangHai> 46
BeiJing> 45
XinJiang> 44
GuangZhou> 43
HeiLongJiang> 42
HuNan> 41
ShangHai> 40
BeiJing> 39
XinJiang> 38
GuangZhou> 37
HeiLongJiang> 36
HuNan> 35
ShangHai> 34
BeiJing> 33
XinJiang> 32
GuangZhou> 31
HeiLongJiang> 30
HuNan> 29
ShangHai> 28
BeiJing> 27
XinJiang> 26
GuangZhou> 25
HeiLongJiang> 24
HuNan> 23
ShangHai> 22
BeiJing> 21
XinJiang> 20
GuangZhou> 19
HeiLongJiang> 18
HuNan> 17
ShangHai> 16
BeiJing> 15
XinJiang> 14
GuangZhou> 13
HeiLongJiang> 12
HuNan> 11
ShangHai> 10
BeiJing> 9
XinJiang> 8
GuangZhou> 7
HeiLongJiang> 6
HuNan> 5
ShangHai> 4
BeiJing> 3
XinJiang> 2
GuangZhou> 1
HeiLongJiang> 0
View Code

这个程序的功能是模拟火车站的售票系统.各个次线程模拟各个省的火车站,互相竞争100张票,抢到票后输出省份的名称以及剩余的票量.主线程监视票量,在票卖完后停止程序

注意一点:Mutex本身并不知道自己负责管理哪个变量,是否对变量进行操作是完全由程序员来进行的.也就是说,假如某一火车站急需车票,它可以无视Mutex,进行暴力抢票.假如它运气不好,碰上几个线程同时访问同一个变量,就会出现票量异常等情况.假如它运气好,那就当什么事都没有发生,多拿了几张票罢了

你也可以用一个Mutex来完成对多个变量的管理,依个人喜好而定

WinApi多线程(CreateThread,CreateMutex,ReleaseMutex)

标签:

原文地址:http://www.cnblogs.com/yanh2001/p/winApiThread20150516.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!