sin的博客

时间悄悄地流过,今天你做了什么
posts - 17, comments - 3, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

WIN32多线程四 线程同步机制Mutex

Posted on 2010-02-23 17:47 sin 阅读(1404) 评论(1)  编辑 收藏 引用 所属分类: WIN32编程
Mutex与CriticalSection相似,都为了处理多个线程对资源的访问。区别是:mutex是内核对象,锁住mutex需要花费更多的时间,mutex可以跨进程存在。没有任何线程拥有mutex,这个mutex处于未激发状态,线程通过调用WaitForXXX来获得此mutex;除非这个线程ReleaseMutex,否则其他线程都不能获得这个mutex的拥有权。
Mutex可以用来解决哲学家就餐问题:让每个哲学家要么获得两根筷子,要么一跟筷子都不获得。哲学家就餐问题中,筷子相当于mutex,每个哲学家要么获得两个mutex,要么一个都不获得。这样就可以防止死锁的发生。

 1 /*
 2  * MTVERYFY.h   <<Win32多线程程序设计>>作者提供的一个非常好用的宏
 3 */
 4 #pragma comment( lib, "USER32" )
 5 
 6 #include <crtdbg.h>
 7 #define MTASSERT(a) _ASSERTE(a)
 8 
 9 
10 #define MTVERIFY(a) if (!(a)) PrintError(#a,__FILE__,__LINE__,GetLastError())
11 
12 __inline void PrintError(LPSTR linedesc, LPSTR filename, int lineno, DWORD errnum)
13 {
14     LPSTR lpBuffer;
15     char errbuf[256];
16 #ifdef _WINDOWS
17     char modulename[MAX_PATH];
18 #else // _WINDOWS
19     DWORD numread;
20 #endif // _WINDOWS
21 
22     FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER
23         | FORMAT_MESSAGE_FROM_SYSTEM,
24         NULL,
25         errnum,
26         LANG_NEUTRAL,
27         (LPTSTR)&lpBuffer,
28         0,
29         NULL );
30 
31     wsprintf(errbuf, "\nThe following call failed at line %d in %s:\n\n"
32         "    %s\n\nReason: %s\n", lineno, filename, linedesc, lpBuffer);
33 #ifndef _WINDOWS
34     WriteFile(GetStdHandle(STD_ERROR_HANDLE), errbuf, strlen(errbuf), &numread, FALSE );
35     Sleep(3000);
36 #else
37     GetModuleFileName(NULL, modulename, MAX_PATH);
38     MessageBox(NULL, errbuf, modulename, MB_ICONWARNING|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
39 #endif
40     exit(EXIT_FAILURE);
41 }

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <Windows.h>
 4 #include "MTVERIFY.h"
 5 
 6 #define NUM_PHIL    5
 7 
 8 HANDLE gChopSticks[NUM_PHIL] = {INVALID_HANDLE_VALUE};  //Mutex句柄,用来表示筷子,即哲学家们争取的资源
 9 static int flag = 1;
10 
11 DWORD WINAPI ThreadFunc(LPVOID);  //线程函数,每个线程代表一个哲学家,哲学家们来争夺筷子(即Mutex)资源
12 
13 int main()
14 {
15     int i;
16     HANDLE hPhil[NUM_PHIL];
17 
18     for (i=0; i<NUM_PHIL; i++)
19     {
20         MTVERIFY( gChopSticks[i] = CreateMutex(NULL, FALSE, NULL) );
21         MTVERIFY( hPhil[i] = CreateThread(NULL, 0, ThreadFunc, (LPVOID)i, 0, NULL) );
22     }
23 
24     Sleep(20000); // 主线程睡眠20000ms,这段时间内,所有哲学家想吃饭的时候,争夺筷子资源
25     flag = 0// 标志置为0,让所有线程都正常退出
26    
27     MTVERIFY( WAIT_OBJECT_0 == WaitForMultipleObjects(NUM_PHIL, hPhil, TRUE, INFINITE) );
28     for (i=0; i<NUM_PHIL; i++)
29     {
30         MTVERIFY( CloseHandle(gChopSticks[i]) );
31         MTVERIFY( CloseHandle(hPhil[i]) );
32     }
33 
34     system("pause");
35     return 0;
36 }
37 
38 DWORD WINAPI ThreadFunc(LPVOID n)
39 {
40     DWORD rc;
41     HANDLE myChopSticks[2];
42     int nIndex = (int)n;
43 
44     while ( flag )
45     {
46         myChopSticks[0= gChopSticks[nIndex%NUM_PHIL];
47         myChopSticks[1= gChopSticks[(nIndex+1)%NUM_PHIL];
48 
49         MTVERIFY( WAIT_OBJECT_0 == WaitForMultipleObjects(2, myChopSticks, TRUE, INFINITE) ); //哲学家等待他身边的两根筷子
50 
51         printf("Philosopher # %d is eating\n", nIndex);
52         Sleep(50);
53 
54         ReleaseMutex(myChopSticks[0]);
55         ReleaseMutex(myChopSticks[1]);
56     }
57 
58     return (DWORD)n;
59 }


Feedback

# re: WIN32多线程四 线程同步机制Mutex  回复  更多评论   

2012-07-24 23:05 by kfqcome
没有任何线程拥有mutex,这个mutex处于未激发状态??
是激发状态(有信号状态)吧!

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理