关键段 互斥量 以及信号量

    xiaoxiao2021-03-25  58

    关键段(主要是用户模式下的线程同步,但是竞争激烈的情况下会进入内核态)

    一般是EnterCriticalSection和LeaveCriticalScetion配对使用,需要先创建一个CRITICAL_SECTION结构。

    下面的函数用来进行初始化

    void InitializerCriticalSection(PCRITICAL_SECTION pcs);

    当线程不在需要访问共享资源的时候,应该调用下面的函数来清理结构

    void deleteCriticalSection(PCRITICAL_SECTION pcs);

    TryEnterCriticalSection从来不会让调用线程进入等待状态,他会通过返回值来表示调用线程是否获准访问资源,因此如果TryEnterCriticalSection发现资源正在被其他线程访问,那么它会返回false。每一个返回true的TryEnterCriticalSection调用必须有一个对应的LeaveCriticalSection。

    互斥量

    要使用互斥量,进程必须先调用CreateMutexl来插件创建一个互斥量

    HANDLE CreateMutex(         PSECURITY_ATTRIBUTES psa,         BOOL bInitialOwner,         PCTSTR pszName);    

     bInitialOwner用来控制互斥量的初始状态。如果传入false,那么表示互斥量不属于任何线程。

    线程ID和递归计数都为0。此时互斥量处于触发状态。如果为true,互斥量的线程ID将被设为主调线程的线程ID,递归计数被设为1。

    OpenMutex来打开一个已存在的互斥量。

    HANDLE OpenMutex(         DWORD dwDesiredAccess,         BOOL bInheritHandle,         PCTSTR pszName);    

    使用WaitForSingleObject和ReleaseMutex配合使用,不需要的时候调用closehandle来释放该句柄

    信号量

    与其他所有内核对象相同,它们也包含一个使用计数,但是它们还包括另外两个32bit值,一个最大资源计数和一个当前资源计数。最大资源计数表示信号量可以控制的最大资源数量,当前资源计数表示信号量当前可用资源的数量。

    信号量的规则如下:

    1.如果当前资源计数大于0,那么信号量处于触发状态

    2.如果当前资源计数等于0,那么信号量处于未触发状态

    3.系统绝对不会让当前资源计数变为负数

    4.当前资源计数绝对不会大于最大资源计数

    创建信号量内核对象:

    HANDLE CreateSomaphore(         PSECURITY_ATTRIBUTE psa,         LONG lInitialCount,         LONG lMaximuCount,         PCTSTR pszName);    lMaximumCount告诉系统应用程序能够处理的资源最大数量。  lInitialCount表示这些资源一开始有多少可供使用。

    任何进程都可以调用OpenSemaphore来得到一个已经存在的信号量的句柄

    HANDLE OpenSemaphore(         DWORD dwDesiredAccess,         BOOL hInheritHandle,         PCTSTR pszName);    线程通过调用ReleaseSemaphore来递增信号量的当前资源计数。 // 信号量对象句柄     HANDLE hSemaphore;     UINT ThreadProc15(LPVOID pParam)     {       // 试图进入信号量关口      WaitForSingleObject(hSemaphore, INFINITE);      // 线程任务处理      AfxMessageBox("线程一正在执行!");      // 释放信号量计数      ReleaseSemaphore(hSemaphore, 1, NULL);      return 0;     }     UINT ThreadProc16(LPVOID pParam)     {       // 试图进入信号量关口      WaitForSingleObject(hSemaphore, INFINITE);      // 线程任务处理      AfxMessageBox("线程二正在执行!");      // 释放信号量计数      ReleaseSemaphore(hSemaphore, 1, NULL);      return 0;     }     UINT ThreadProc17(LPVOID pParam)     {       // 试图进入信号量关口      WaitForSingleObject(hSemaphore, INFINITE);      // 线程任务处理      AfxMessageBox("线程三正在执行!");      // 释放信号量计数      ReleaseSemaphore(hSemaphore, 1, NULL);      return 0;     }     ……     void CSample08View::OnSemaphore()      {      // 创建信号量对象      hSemaphore = CreateSemaphore(NULL, 2, 2, NULL);      // 开启线程      AfxBeginThread(ThreadProc15, NULL);      AfxBeginThread(ThreadProc16, NULL);      AfxBeginThread(ThreadProc17, NULL);     }   
    转载请注明原文地址: https://ju.6miu.com/read-36387.html

    最新回复(0)