zoukankan      html  css  js  c++  java
  • 对windows 线程同步的个人见解

     Windows上线程同步有四种类型: 临界区(CRITICAL_SECTION) ,互斥(Mutex) , 信号量(semahpore),事件(Event);

     1: 临界区(CRITICAL_SECTION) ,临界区是一段代码,在任意给定的时刻只能被一个线程使用,

        如果多个线程企图同时访问临界区,则一次只允许一个线程控区临界区,其余所有线程将被阻塞或保

      持等待,直到临界区被释放出来.

        基本用法:

             //define a global  critical_section

         CRITICAL_SECTION cs;

                void threadproc1(void)

         {

           EnterCriticalSection(&cs);

           //TODO: do sth for here

                        .......

                       LeaveCriticalSection(&cs);

        }

         void main()

          {

           InitializeCriticalSection(&cs);

             ......

           _beginthread(threadproc1,0,NULL);

           DeleteCriticalSection(&cs);

          }

      2:互斥(Mutex) : 一个互斥对象一次只能被一个线程拥有;跟临界区类似,但比临界区复杂.

        基本用法:

             //define a global handle for mutex

            HANDLE ghMutex;

            DWORD WINAPI ThreadProc(LPVOID lpParam)

            {

                 WaitForSingleObject(ghMutex,INFINITE);//获得互斥体对象

              ....

              ReleaseMutex(ghMutex); //交出互斥对象给其它线程使用.

            }

         void main()

         {

           //create a mutex

            ghMutex = CreateMutex(NULL,FALSE,NULL);//注意中间那个FALSE,具体参考MSDN;

            CreateThread(threadProc..);

            //

          }

            3: 信号量 (semahpore) 当应用程序中的多个线程要访问某一资源.可以使用信号量,它并不限制资源一次只被

        一个线程访问.

          基本用法:

          void threadproc(LPVOID lpvoid)

          {

          WaitForSingleObject(hsemaphore,INFINITE);//调用一次,信号量计数减1;为0时,阻塞.

            ..........

            ReleaseSemaphore(hsemaphore,1,NULL);//恢复一个信号量计数 

         }

        void main()

          {

            HANDLE hsemaphore = CreateSemaphore(NULL,3,3,NULL);

          }

       4 :事件(EVENT) ;应用程序在访问某一资源前必须要等待某一事件发生.

        基本用法:

         void main()

           {

              HANDLE hEvent = CreateEvent(NULL,FALSE,TRUE,NULL);

              //注意 第二个参数,与第三个参数意义, 要不要手动调用SetEvent(),ResetEvent()都取决于他们.

              hThread1 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadProc1,NULL,0,NULL);

            }

          DWORD WINAPI ThreadProc2(LPVOID lpParam)

          {

             DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);//事件有信号,就立即返回,否则阻塞.

           if(WAIT_OBJECT_0 == dReturn)

            {   

             cout <<"Thread1 signaled!"<<endl;

            }

          }

            注意,同步对象在使用完之后,都要使用 CloseHandle()将其释放.

  • 相关阅读:
    5.4 类型转换
    IntelliJ IDEA 创建Web项目(全教程)
    Spring IoC 依赖注入的方法大全 XML配置方式
    20秒教你如何写maven2的pom文件的依赖包
    数据库面试题之COUNT(*),COUNT(字段),CONUT(DISTINCT 字段)的区别
    Oracle中的单行函数
    Select 子句后的别名,在where条件中不能使用
    Oracle SQL*Plus命令
    使用js请求Servlet时的路径
    idea 创建运行web项目时,报错: Can not issue executeUpdate() for SELECTs解决方案
  • 原文地址:https://www.cnblogs.com/luisfan/p/2947027.html
Copyright © 2011-2022 走看看