线程同步与异步套接字编程(二)

接下来我们介绍利用关键代码段实现线程同步的方法。

关键代码段(临界区)工作在用户方式下。它是指一个小代码段,在代码能够执行前,它必须独占对某些资源的访问权。

关键代码段机制,创建---进入---离开---删除.

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.

谢谢.

原文地址:https://www.cnblogs.com/lumao1122-Milolu/p/11811798.html

时间: 2024-11-09 22:37:28

线程同步与异步套接字编程(二)的相关文章

第16章 线程同步与异步套接字

转自: https://blog.csdn.net/u014162133/article/details/46573873 原文地址:https://www.cnblogs.com/happykoukou/p/9379167.html

【转】 VC中TCP实现 异步套接字编程的原理+代码

所谓的异步套接字编程就是  调用了 如下函数   WSAAsyncSelect   设置了 套接字的状态为异步,有关函数我会在下面详细介绍... 异步套接字解决了 套接字编程过程中的堵塞问题 ...... 什么是堵塞?请看下面  你可能有过这样的体会  在  VC编写基于界面的网路程序时候  ,调用 recv recvfrom   accept  等函数的时候 整个程序的主线程进入堵塞状态直到 有连接或者信息的到来.  我们可以利用多线程的方法解决主线程堵塞的问题,但是我们如果一个程序需要多个套

多线程编程——线程同步与异步

1.多线程和异步操作的异同 多线程和异步操作两者都可以达到避免调用线程阻塞的目的,从而提高软件的可响应性.甚至有些时候我们就认为多线程和异步操作是等同的概念.但是,多线程和异步操作还是有一些区别的.而这些区别造成了使用多线程和异步操作的时机的区别. 2.异步操作的本质 所有的程序最终都会由计算机硬件来执行,所以为了更好的理解异步操作的本质,我们有必要了解一下它的硬件基础. 熟悉电脑硬件的朋友肯定对DMA这个词不陌生,硬盘.光驱的技术规格中都有明确DMA的模式指标,其实网卡.声卡.显卡也是有DMA

Windows异步套接字(WSASocket)

异步套接字: 如果使用阻塞的套接字的话,在控制台下还好!如果是WIN32程序的话,那么就容易造成界面的假死,因为接收函数一直等待有消息进来之后才会被返回!所以此时界面一直属于假死的状态,如果你乱动的话,那么就容易真死了.解决办法如下: 第一:使用多线程技术,多线程和SOCKET结合的话,可以使用单独一个线程来接收消息.这样即使接收函数阻塞了也不会影响其他线程,例如界面线程.但是如果使用多线程的话,就必须要考虑到多线程之间同步的问题,以及临界资源的问题. 第二:使用异步套接字.但是使用异步套接字的

TCP下的套接字编程

1.什么是套接字 应用层通过传输层进行数据通信时,TCP和UDP会遇到同时为多个应用程序进程提供并发服务的问题.多个TCP连接或多个应用程序进程可能需要通过同一个TCP协议端口传输数据.为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了称为套接字(Socket)的接口.区分不同应用程序进程间的网络通信和连接,主要有3个参数:通信的目的IP地址.使用的传输层协议(TCP或UDP)和使用的端口号.Socket原意是"插座".通过将这3个参数结合起来,

socket套接字编程

socket套接字编程 客户端/服务器架构 1.硬件C/S架构(打印机) 2.软件C/S架构 互联网中处处是C/S架构 如黄色网站是服务端,你的浏览器是客户端(B/S架构也是C/S架构的一种) 腾讯作为服务端为你提供视频,你得下个腾讯视频客户端才能看它的视频) C/S架构与socket的关系: 我们学习socket就是为了完成C/S架构的开发         详见网络通信原理   socket是什么 Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Soc

探索UDP套接字编程

UDP和TCP处于同一层网络模型中,也就是运输层,基于二者之上的应用有很多,常见的基于TCP的有HTTP.Telnet等,基于UDP有DNS.NFS.SNMP等.UDP是无连接,不可靠的数据协议服务,而TCP提供面向流.提供可靠数据服务.注意,UDP和TCP没有好坏之分,只是二者的适用场景不同罢了. 典型的UDP套接字编程模型是客户端不予服务端建立连接,而只是调用sendto函数来向服务端发送数据,其中必须要指定服务端的信息,包括IP和端口等:服务端不接收来自客户端的连接,而只是调用recvfr

【转】 探索UDP套接字编程

UDP和TCP处于同一层网络模型中,也就是运输层,基于二者之上的应用有很多,常见的基于TCP的有HTTP.Telnet等,基于UDP有DNS.NFS.SNMP等.UDP是无连接,不可靠的数据协议服务,而TCP提供面向流.提供可靠数据服务.注意,UDP和TCP没有好坏之分,只是二者的适用场景不同罢了. 典型的UDP套接字编程模型是客户端不予服务端建立连接,而只是调用sendto函数来向服务端发送数据,其中必须要指定服务端的信息,包括IP和端口等:服务端不接收来自客户端的连接,而只是调用recvfr

Linux 套接字编程中的 5 个隐患

在异构环境中开发可靠的网络应用程序 M. Tim Jones ([email protected]), 资深软件工程师, Emulex 简介: Socket API 是网络应用程序开发中实际应用的标准 API.尽管该 API 简单,但是开发新手可能会经历一些常见的问题.本文识别一些最常见的隐患并向您显示如何避免它们. 发布日期: 2005 年 10 月 08 日 级别: 中级 访问情况 : 13059 次浏览 评论: 0 (查看 | 添加评论 - 登录)  平均分 (34个评分)为本文评分 在