线程同步与异步套接字编程
Posted lumao1122-milolu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程同步与异步套接字编程相关的知识,希望对你有一定的参考价值。
接下来我们介绍利用关键代码段实现线程同步的方法。
关键代码段(临界区)工作在用户方式下。它是指一个小代码段,在代码能够执行前,它必须独占对某些资源的访问权。
关键代码段机制,创建---进入---离开---删除.
1 InitializeCriticalSection( 2 LPCRITICAL_SECTION lpCriticalSection 3 );
创建初始化函数参数是一个out类型,即作为返回值使用。因此在之前我们需要构造一个CRITICAL_SECTION结构型对象,然后将该对象地址传递给InitializeCriticalSection函数,由系统自动维护该对象。
进入关键代码段函数:EnterCriticalSection
离开关键代码段函数:LeaveCriticalSetion
删除函数: DeleteCriticalSection
这三个函数都只有一个参数,该参数为CRITICAL_SECTION结构型对象指针。
接下来将之前的例程用关键代码段来实现多线同步处理:
1 #include<windows.h> 2 #include<iostream.h> 3 4 DWORD WINAPI Fun1Proc(LPVOID lpParameter); 5 DWORD WINAPI Fun2Proc(LPVOID lpParameter); 6 7 int tick=100; 8 //HANDLE hMutex; 9 //HANDLE g_hEvent; 10 CRITICAL_SECTION g_cs; 11 void main() 12 { 13 HANDLE hThread1; 14 HANDLE hThread2; 15 /*g_hEvent=CreateEvent(NULL,FALSE,FALSE,"MyThread"); 16 if(g_hEvent) 17 { 18 if(ERROR_ALREADY_EXISTS==GetLastError()) 19 { 20 cout<<"Only one intance can run."<<endl; 21 return; 22 } 23 } 24 SetEvent(g_hEvent);*/ 25 InitializeCriticalSection(&g_cs); 26 hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL); 27 hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL); 28 CloseHandle(hThread1); 29 CloseHandle(hThread2); 30 //Create mutex object. 31 //hMutex=CreateMutex(NULL,TRUE,"dadad"); 32 /*if(hMutex) 33 { 34 if(ERROR_ALREADY_EXISTS==GetLastError()) 35 { 36 cout<<"Only one intance can run."<<endl; 37 return; 38 } 39 } 40 WaitForSingleObject(hMutex,INFINITE); 41 ReleaseMutex(hMutex); 42 ReleaseMutex(hMutex);*/ 43 44 Sleep(4000); 45 //CloseHandle(g_hEvent); 46 DeleteCriticalSection(&g_cs); 47 } 48 //thread function 49 DWORD WINAPI Fun1Proc(LPVOID lpParameter) 50 { 51 while(true) 52 { 53 //request object using 54 //WaitForSingleObject(hMutex,INFINITE); 55 //WaitForSingleObject(g_hEvent,INFINITE); 56 //ResetEvent(g_hEvent); 57 Sleep(1); 58 EnterCriticalSection(&g_cs); 59 Sleep(1); 60 if(tick>0) 61 { 62 //Sleep(1); 63 cout<<"Thread1 sell tick:"<<tick--<<endl; 64 //SetEvent(g_hEvent); 65 LeaveCriticalSection(&g_cs); 66 } 67 else 68 { 69 //SetEvent(g_hEvent); 70 LeaveCriticalSection(&g_cs); 71 break; 72 } 73 //ReleaseMutex(hMutex); 74 } 75 return 0; 76 } 77 //thread function 78 DWORD WINAPI Fun2Proc(LPVOID lpParameter) 79 { 80 81 while(true) 82 { 83 //request object using 84 //WaitForSingleObject(hMutex,INFINITE); 85 //WaitForSingleObject(g_hEvent,INFINITE); 86 //ResetEvent(g_hEvent); 87 Sleep(1); 88 EnterCriticalSection(&g_cs); 89 Sleep(1); 90 if(tick>0) 91 { 92 //Sleep(1); 93 cout<<"Thread2 sell tick:"<<tick--<<endl; 94 //SetEvent(g_hEvent); 95 LeaveCriticalSection(&g_cs); 96 } 97 else 98 { 99 //SetEvent(g_hEvent); 100 LeaveCriticalSection(&g_cs); 101 break; 102 } 103 //ReleaseMutex(hMutex); 104 } 105 return 0; 106 }
我们在进入临界区之前用了个延时,预留给两线程之间交替时间间隔。
编译运行,结果和之前的一样。
当然了,临界代码区有速度快,但容易出现锁死的情况,例如:
1 //thread function 2 DWORD WINAPI Fun1Proc(LPVOID lpParameter) 3 { 4 while(true) 5 { 6 //request object using 7 //WaitForSingleObject(hMutex,INFINITE); 8 //WaitForSingleObject(g_hEvent,INFINITE); 9 //ResetEvent(g_hEvent); 10 Sleep(1); 11 EnterCriticalSection(&g_cs0); 12 Sleep(1); 13 EnterCriticalSection(&g_cs); 14 ...... 15 } 16 //thread function 17 DWORD WINAPI Fun2Proc(LPVOID lpParameter) 18 { 19 20 while(true) 21 { 22 //request object using 23 //WaitForSingleObject(hMutex,INFINITE); 24 //WaitForSingleObject(g_hEvent,INFINITE); 25 //ResetEvent(g_hEvent); 26 Sleep(1); 27 EnterCriticalSection(&g_cs); 28 Sleep(1); 29 EnterCriticalSection(&g_cs0); 30 if(tick>0) 31 ..... 32 }
这情况就出现了锁死的情况。是编写代码的时候必须要注意避免的。这也是其与互斥对象,事件对象有较大区别的地方。
End.
谢谢.
以上是关于线程同步与异步套接字编程的主要内容,如果未能解决你的问题,请参考以下文章
27 Apr 18 GIL 多进程多线程使用场景 线程互斥锁与GIL对比 基于多线程实现并发的套接字通信 进程池与线程池 同步异步阻塞非阻塞