zoukankan      html  css  js  c++  java
  • 线程同步与异步套接字编程(二)

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

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

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

    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.

    谢谢.

  • 相关阅读:
    java-version
    Centos7使用google-Chrome浏览器
    sign_and_send_pubkey: signing failed: agent refused operation
    删除带中划线的数据库
    yum update报错RPM数据库问题
    Centos的timedatectl
    /var/lib/docker/overlay2/db72dadf047395c178feb0eaedd932b48e283abcaa5a870c0c746bab8ee6f76a: no such file or directory
    /bin/bash^M: 坏的解释器: 没有那个文件或目录
    repeat()函数
    (Problem 47)Distinct primes factors
  • 原文地址:https://www.cnblogs.com/lumao1122-Milolu/p/11811798.html
Copyright © 2011-2022 走看看