打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
临界区实现线程同步互斥
userphoto

2014.02.13

关注

除了临界区对象进能够被用于一个进程内的线程使用外,临界区对象同于其他互斥体对象一样,也可以提供同步机制.事件,互斥体和信号量对象也能够被用于单个进程实现资源互斥访问,与此相比,为了实现同步互斥访问共享资源,临界区对象提供一种更加轻巧,快速和有效的机制.象互斥体对象一样,临界区对象也可以被一个使用它来阻止同步访问共享资源的线程所用于.例如:一个进程随时可以使用一个临界区对象来阻止其他线程修改一个局数据结构.
进程负责为一个临界区分配内存.典型地,就是宣布一个CRITICAL_SECTION类型的变量.线程在使用它之前,临界区对象必须使用InitializeCriticalSection函数进行初始化.线程使用EnterCriticalSection或TryEnterCriticalSection函数获取临界区所有权,并通过LeaveCriticalSection函数释放临界区所用权.如果当前临界区对象被其他线程所拥有,EnterCriticalSection将无限等待为了临界区所有权.相比之下,一个互斥体对象为了互斥,等待函数会有一个指定的时间段.TryEnterCriticalSection函数无阻塞正在调用的线程而进入临界区.
一旦线程拥有临界区,它必须额外的调用EnterCriticalSection或无阻塞他的执行的TryEnterCriticalSection函数.这样以来,当等待一个已存在的临界区的拥有权时,就不会出现死锁自己.每当它进入临界区时,就必须调用LeaveCriticalSection来释放对临界区的拥有权.
当临界区被初始化之后,进程内的任一个线程都可以调用DeleteCriticalSection函数来释放被分配了的系统资源.DeleteCriticalSection函数被调用之后,这个临界区对象就不能够再被拥有为了同步机制了.
一旦一个临界区对象被特有化之后,通过调用EnterCriticalSection函数而关联度其它的线程将等待为了它的拥有权.没有等到拥有权的线程释

放去继续运行.
SECTICAL_SECTION结构:
typedef struct _RTL_CRITICAL_SECTION {
    PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
    //
    //  The following three fields control entering and exiting the critical
    //  section for the resource
    //
    LONG LockCount;
    LONG RecursionCount;
    HANDLE OwningThread;        // from the thread's ClientId->UniqueThread
    HANDLE LockSemaphore;
    ULONG_PTR SpinCount;        // force size on 64-bit systems when packed
} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;
typedef RTL_CRITICAL_SECTION CRITICAL_SECTION;
typedef PRTL_CRITICAL_SECTION PCRITICAL_SECTION;
typedef PRTL_CRITICAL_SECTION LPCRITICAL_SECTION;

操作临界区的相关函数
(1)  InitializeCriticalSection
   初始化一个临界区对象,而临界区对象(数据成员)由系统自动维护.
   VOID InitializeCriticalSection(
       LPCRITICAL_SECTION lpCriticalSection //pointer to critical section object
   ); 
(2) DeleteCriticalSection 
    释放一个没有被占有的临界区对象的所有资源.
    VOID DeleteCriticalSection(
        LPCRITICAL_SECTION lpCriticalSection //pointer to critical section object     
    );
(3)  EnterCriticalSection
   用来等待临界区对象的所有权,当调用线程赋予所有权,本函数返回,如果没能等待到,那么导致线程暂停.
    VOID EnterCriticalSection(
       LPCRITICAL_SECTION lpCriticalSection //pointer to critical section object
    );
(4)  LeaveCriticalSection
   释放指定临界区对象所有权
   void LeaveCriticalSection(
       LPCRITICAL_SECTION lpCriticalSection //pointer to critical section object
   ); 
例子:
CRITICAL_SECTION g_cs; //临界区对象
void main()
{
   HANDLE thread1 = CreateThread(NULL, 0, Fun1Proc, NULL, 0, NULL);
   HANDLE thread2 = CreateThread(NULL, 0, Fun2Proc, NULL, 0, NULL);
   CloseHandle(thread1);
   CloseHandle(thread2);
   //初始化一个临界区对象
   InitializeCriticalSection(&g_cs);
   Sleep(4000);
   //释放一个没有被占有的临界区对象的所有资源 
   DeleteCriticalSection(&g_cs);

}

DWORD WINAPI Fun1Proc(LPVOID lpParam)
{
   while(TRUE)
   {
       EnterCriticalSection(&g_cs);
       if (ticket>0)
       {
          cout<<"thread1 sells: "<<ticket--<<endl;
          Sleep(1);
       }
       else
          break;
       LeaveCriticalSection(&g_cs);
   }
   return 0;
}

DWORD WINAPI Fun1Proc(LPVOID lpParam)
{
   while(TRUE)
   {
       EnterCriticalSection(&g_cs);
       if (ticket>0)
       {
          cout<<"thread2 sells: "<<ticket--<<endl;
          Sleep(1);
       }
       else
          break;
       LeaveCriticalSection(&g_cs);
   }
   return 0;
}

//以下是我自己编写实现临界区的类:
//头文件 CriticalSection.h
#pragma once
class CCriticalSection
{
private:
       CRITICAL_SECTION m_CS;
public:
       CCriticalSection()
       {
           ::InitializeCriticalSection(&m_CS);
       }
       ~CCriticalSection()
       {
           ::DeleteCriticalSection(&m_CS);
       }
       operator LPCRITICAL_SECTION()
       {
           return &m_CS;
       }
       void Lock()
       {
           ::EnterCriticalSection(&m_CS);
       }
       void UnLock()
       {
           ::LeaveCriticalSection(&m_CS);
       }
}; 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
理解EnterCriticalSection 临界区
WinCE下临界区CriticalSection使用
VC 6.0调试篇:定位临界区(critical section)导致的死锁
Mutex和Critical_Section都是主要用于限制多线程
对CRITICAL_SECTION理解的总结 - 雨巷叮当的日志 - 网易博客
临界区
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服