线程同步与异步套接字编程

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对比 基于多线程实现并发的套接字通信 进程池与线程池 同步异步阻塞非阻塞

高性能网络IO模型

TCP套接字连接中同步与异步的优势

Python网络编程通过ThreadingMixIn实现多线程异步套接字程序

python网络编程基础(线程与进程并行与并发同步与异步)

异步编程