Win32替代pthread

时间:2014-01-21 06:48:33

标签: c++ winapi pthreads win32-process

是否可以使用标准的win32 CreateMutex样式代码编写它。我只是想知道我是否想在我们的应用程序中引入一个新库,或者我是否可以找到一种方法来自己编写。我只是无法弄清楚如何在CriticalSection内等待。这是我目前使用pthread库的工作代码。

T remove() {
    pthread_mutex_lock(&m_mutex);
    while (m_queue.size() == 0) {
        pthread_cond_wait(&m_condv, &m_mutex);
    }
    T item = m_queue.front();
    m_queue.pop_front();
    pthread_mutex_unlock(&m_mutex);
    return item;
}

3 个答案:

答案 0 :(得分:3)

对于VC-2012之前的支持,最好的选择是Boost.Thread,它支持条件变量。

答案 1 :(得分:2)

这是我的尝试。这不是win32中条件等待锁的最佳实现,但我认为它有效。它可以使用仔细的代码审查审查。

一个警告 - 它不一定保证有序的公平性,因为所有等待的线程可能最初被阻止等待事件。调度程序将在此时恢复所有线程以继续运行(直到后续阻塞的EnterCriticalSection调用),但不一定按照线程到达remove()调用开始的相同顺序。对于大多数应用程序来说,这可能只是少数几个线程,但这是大多数线程框架保证的。

其他警告 - 为简洁起见,我忽略了检查所有这些Win32 API的返回值的重要步骤。

CRITICAL_SECTION m_cs;
HANDLE m_event;

void Init()
{
   InitializeCriticalSection(&m_cs);
   m_event = CreateEvent(NULL, TRUE, FALSE, NULL); // manual reset event
}

void UnInit()
{
    DeleteCriticalSection(&m_cs);
    CloseHandle(m_event);
    m_event = NULL;
}

T remove()
{
    T item;
    bool fGotItem = false;
    while (fGotItem == false)
    {
        // wait for event to be signaled
        WaitForSingleObject(m_event, INFINITE);

        // wait for mutex to become available
        EnterCriticalSection(&m_cs);

        // inside critical section
        {
            // try to deque something - it’s possible that the queue is empty because another 
            // thread pre-empted us and got the last item in the queue before us

            size_t queue_size = m_queue.size();

            if (queue_size == 1)
            {
               // the queue is about to go empty
               ResetEvent(m_event);
            }

            if (queue_size > 0)
            {
                fGotItem = true;
                item = m_queue.front();

                m_queue.pop();        
            }
        }

        LeaveCriticalSection(&m_cs);

    }

    return item;
}

void Add(T& item)
{
    // wait for critical section to become available
    EnterCriticalSection(&m_cs);

    // inside critical section
    {
        m_queue.push_back(item);

        SetEvent(m_event); // signal other threads that something is available
    }

    LeaveCriticalSection(&m_cs);
}

答案 2 :(得分:1)

Windows Vista为这种情况引入了新的原生Win32 Conditional VariableSlim Reader/Writer Lock原语,例如:

使用关键部分:

CRITICAL_SECTION m_cs;
CONDITION_VARIABLE m_condv;

InitializeCriticalSection(&m_cs);
InitializeConditionVariable(&m_condv);

...

void add(T item)
{ 
    EnterCriticalSection(&m_cs);
    m_queue.push_back(item);
    LeaveCriticalSection(&m_cs);
    WakeConditionVariable(&m_condv);
}

T remove()
{ 
    EnterCriticalSection(&m_cs);
    while (m_queue.size() == 0)
        SleepConditionVariableCS(&m_condv, &m_cs, INFINITE);
    T item = m_queue.front();
    m_queue.pop_front();
    LeaveCriticalSection(&m_cs);
    return item;
}

使用SRW锁:

SRWLOCK m_lock;
CONDITION_VARIABLE m_condv;

InitializeSRWLock(&m_lock);
InitializeConditionVariable(&m_condv);

...

void add(T item)
{ 
    AcquireSRWLockExclusive(&m_lock);
    m_queue.push_back(item);
    ReleaseSRWLockExclusive(&m_lock);
    WakeConditionVariable(&m_condv);
}

T remove()
{ 
    AcquireSRWLockExclusive(&m_lock);
    while (m_queue.size() == 0)
        SleepConditionVariableSRW(&m_condv, &m_lock, INFINITE, 0);
    T item = m_queue.front();
    m_queue.pop_front();
    ReleaseSRWLockExclusive(&m_lock);
    return item;
}