如果是问windows环境下同步的方法有哪些?
回答:互斥锁、事件、互斥量、信号量;
同步,意在合作的关系,如:线程A和线程B,线程A执行完某操作后,立马通知线程B(线程B之前应该是挂起状态)执行。
互斥,意在对资源的唯一占有的强调,如:线程A和线程B,对于全局变量或静态变量(共享内存区)的唯一占有。线程A在访问共享内存区时,不运行线程B访问。反之亦然。互斥有同步的形式表现:线程A占有共享内存区完成访问后,系统会概率性的跳到线程B挂起的状态,这时共享内存区允许访问。
不同:
互斥不关心合作,重点在维护共享内存区的唯一访问条件。
同步重点在合作。
所以,上面的问题回答是不正确的。同步的方法只有事件和信号量。【具体的方法描述:该链接】
如果,不用同步方法做出同步效果,可以使用线程通信 技术来完成。
如下:模拟五个不同子线程使用线程通信实现同步效果的程序。
1 #include <windows.h> 2 #include <iostream> 3 using namespace std; 4 5 long g_nNum = 0; 6 const int THREAD_NUM = 5; 7 DWORD WINAPI Fun1 (LPVOID lpThreadParameter); 8 DWORD WINAPI Fun2 (LPVOID lpThreadParameter); 9 DWORD WINAPI Fun3 (LPVOID lpThreadParameter); 10 DWORD WINAPI Fun4 (LPVOID lpThreadParameter); 11 DWORD WINAPI Fun5 (LPVOID lpThreadParameter); 12 13 DWORD nHandleThreadID[THREAD_NUM] = {0}; 14 HANDLE handle[THREAD_NUM]; 15 16 #define TALK_MESSAGE WM_USER + 1 17 18 19 int main() 20 { 21 int p[THREAD_NUM] = {0}; 22 for(int i=0;i<THREAD_NUM;i++) 23 { 24 switch(i) 25 { 26 case 0: 27 handle[i] = (HANDLE)CreateThread(NULL, 0, Fun1, 0, 0, NULL); 28 nHandleThreadID[i] = GetThreadId(handle[i]); 29 break; 30 case 1: 31 handle[i] = (HANDLE)CreateThread(NULL, 0, Fun2, 0, 0, NULL); 32 nHandleThreadID[i] = GetThreadId(handle[i]); 33 break; 34 case 2: 35 handle[i] = (HANDLE)CreateThread(NULL, 0, Fun3, 0, 0, NULL); 36 nHandleThreadID[i] = GetThreadId(handle[i]); 37 break; 38 case 3: 39 handle[i] = (HANDLE)CreateThread(NULL, 0, Fun4, 0, 0, NULL); 40 nHandleThreadID[i] = GetThreadId(handle[i]); 41 break; 42 case 4: 43 handle[i] = (HANDLE)CreateThread(NULL, 0, Fun5, 0, 0, NULL); 44 nHandleThreadID[i] = GetThreadId(handle[i]); 45 break; 46 } 47 } 48 49 WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE); 50 51 return 0; 52 } 53 54 55 DWORD WINAPI Fun1(LPVOID lpThreadParameter) 56 { 57 Sleep(10); // 等待Fun2、Fun3...的消息队列创建. 58 59 DWORD nThreadId = GetCurrentThreadId(); 60 g_nNum++; //访问全局变量,所有线程共享内存区 61 printf("线程编号为%d 全局资源值为%d ", nThreadId, g_nNum); 62 PostThreadMessage (nHandleThreadID[1], TALK_MESSAGE, 0, 0); 63 64 return 0; 65 } 66 67 DWORD WINAPI Fun2 (LPVOID lpThreadParameter) 68 { 69 MSG msg; 70 while( GetMessage(&msg, 0, 0, 0) ) 71 { 72 if(msg.message == TALK_MESSAGE) 73 { 74 PostMessage (NULL, WM_QUIT, 0, 0); 75 } 76 DispatchMessage(&msg); 77 } 78 79 DWORD nThreadId = GetCurrentThreadId(); 80 g_nNum++; 81 printf("线程编号为%d 全局资源值为%d ", nThreadId, g_nNum); 82 PostThreadMessage (nHandleThreadID[2], TALK_MESSAGE, 0, 0); 83 84 85 return 0; 86 } 87 88 DWORD WINAPI Fun3 (LPVOID lpThreadParameter) 89 { 90 91 MSG msg; 92 while( GetMessage(&msg, 0, 0, 0) ) 93 { 94 if(msg.message == TALK_MESSAGE) 95 { 96 PostMessage (NULL, WM_QUIT, 0, 0); 97 } 98 DispatchMessage(&msg); 99 } 100 101 DWORD nThreadId = GetCurrentThreadId(); 102 g_nNum++; 103 printf("线程编号为%d 全局资源值为%d ", nThreadId, g_nNum); 104 PostThreadMessage (nHandleThreadID[3], TALK_MESSAGE, 0, 0); 105 106 return 0; 107 } 108 109 DWORD WINAPI Fun4 (LPVOID lpThreadParameter) 110 { 111 MSG msg; 112 while( GetMessage(&msg, 0, 0, 0) ) 113 { 114 if(msg.message == TALK_MESSAGE) 115 { 116 PostMessage (NULL, WM_QUIT, 0, 0); 117 } 118 DispatchMessage(&msg); 119 } 120 121 DWORD nThreadId = GetCurrentThreadId(); 122 g_nNum++; 123 printf("线程编号为%d 全局资源值为%d ", nThreadId, g_nNum); 124 PostThreadMessage (nHandleThreadID[4], TALK_MESSAGE, 0, 0); 125 126 return 0; 127 } 128 129 DWORD WINAPI Fun5 (LPVOID lpThreadParameter) 130 { 131 MSG msg; 132 while( GetMessage(&msg, 0, 0, 0) ) 133 { 134 if(msg.message == TALK_MESSAGE) 135 { 136 PostMessage (NULL, WM_QUIT, 0, 0); 137 } 138 DispatchMessage(&msg); 139 } 140 141 DWORD nThreadId = GetCurrentThreadId(); 142 g_nNum++; 143 printf("线程编号为%d 全局资源值为%d ", nThreadId, g_nNum); 144 //PostThreadMessage (nHandleThreadID[1], TALK_MESSAGE, 0, 0); 145 146 return 0; 147 }
访问顺序为: Fun1完成通知Fun2,Fun2完成通知Fun3,Fun3完成通知Fun4,Fun4完成通知Fun5.
执行结果:
线程编号为4740 全局资源值为1
线程编号为2484 全局资源值为2
线程编号为2408 全局资源值为3
线程编号为3564 全局资源值为4
线程编号为1460 全局资源值为5
请按任意键继续. . .
=================================
做到对共享内存区的同步访问。
注:加深理解互斥和同步技术,如果真的是需要实现同步时,最好还是用事件、信号量技术。