行云

行至水穷处,坐看云起时。

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

所谓临界区就是同一时刻只能有一个线程访问的代码段。处于临界区的代码通常都是需要被多个线程访问,但又只能顺序访问的。
一般就是共享的数据。用于实现顺序访问临界区的方式有多种,互斥量、信号量、事件都可以实现。
下面的方式是采用互斥量实现一个类,比直接使用互斥量方便、直观。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifndef WIN32
 #include <pthread.h>
#else
#include <windows.h>
#endif

#ifdef WIN32
typedef HANDLE pthread_mutex_t;
#endif
class CCriticalSection
{
public:
    CCriticalSection(pthread_mutex_t& lock);
    ~CCriticalSection();

public:
    static void enterCS(pthread_mutex_t& lock);
    static void leaveCS(pthread_mutex_t& lock);
    
private:
    pthread_mutex_t& m_Mutex;            // Alias name of the mutex to be protected
    int m_iLocked;                       // Locking status

//    CGuard& operator=(const CGuard&);
};

//
// Automatically lock in constructor
// 这里需要提供一个全局的互斥量为参数
// 临界区是为了实现多个线程顺序访问共享数据,显然应该要有一个
// 多个线程可以访问的变量才能实现,如果在构造函数中创建一个互斥量,
// 这个互斥量对其它线程来说是不可见的,当然就无法实现与其它线程的互斥访问
CCriticalSection::CCriticalSection(pthread_mutex_t& lock):
m_Mutex(lock),
    m_iLocked()
{
#ifndef WIN32
    m_iLocked = pthread_mutex_lock(&m_Mutex);
#else
    m_iLocked = WaitForSingleObject(m_Mutex, INFINITE);
#endif
}

// Automatically unlock in destructor
CCriticalSection::~CCriticalSection()
{
#ifndef WIN32
    if (0 == m_iLocked)
        pthread_mutex_unlock(&m_Mutex);
#else
    if (WAIT_FAILED != m_iLocked)
        ReleaseMutex(m_Mutex);
#endif
}
//相当于WaitForSingleObject更直观的表述
void CCriticalSection::enterCS(pthread_mutex_t& lock)
{
#ifndef WIN32
    pthread_mutex_lock(&lock);
#else
    WaitForSingleObject(lock, INFINITE);
#endif
}

//相当于ReleaseMutex更直观的表述
void CCriticalSection::leaveCS(pthread_mutex_t& lock)
{
#ifndef WIN32
    pthread_mutex_unlock(&lock);
#else
    ReleaseMutex(lock);
#endif
}

pthread_mutex_t g_mutex = CreateMutex(NULL, FALSE, NULL);
DWORD WINAPI worker(LPVOID lpParameter)
{
    DWORD id = GetCurrentThreadId();
    while (1)
    {
        CCriticalSection cs(g_mutex); //作用范围是本次循环
        printf("id: %u\n", id);
        
    }
}

int main(int argc, char **argv)
{
    for (int i=0; i<3; i++)
        CreateThread(NULL, 0, worker, NULL, 0, NULL);
    Sleep(20000);
    return 0;
}

 如果没有互斥处理输出可能是这样的:

加上互斥处理后,输出类似这样:

三个线程按顺序获得了锁,具有均等的运行机会。

posted on 2013-03-26 08:21  windflying  阅读(578)  评论(0编辑  收藏  举报