Mutex与CriticalSection相似,都为了处理多个线程对资源的访问。区别是:mutex是内核对象,锁住mutex需要花费更多的时间,mutex可以跨进程存在。没有任何线程拥有mutex,这个mutex处于未激发状态,线程通过调用WaitForXXX来获得此mutex;除非这个线程ReleaseMutex,否则其他线程都不能获得这个mutex的拥有权。
Mutex可以用来解决哲学家就餐问题:让每个哲学家要么获得两根筷子,要么一跟筷子都不获得。哲学家就餐问题中,筷子相当于mutex,每个哲学家要么获得两个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 }
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 }
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 }