开发者

Condition Variable alternatives (c/c++ on windows xp)

I want to write a thread which runs tasks from an unlimited-size container of tasks.

While the task-list is empty the thread trying to get a task should be blocked.

Coming from Linux I wanted to use condition variable which will be signaled on task adding and will be waited while the list is empty.

I found that CONDITION_VARIABLE is available only from windows Vista, so this is out of question. Semaphores are problematic too due to the unlimited-s开发者_JAVA技巧ize restriction.

Is there any apropriate subtitution?

Thanks


Why do you say that semaphores are problematic? Linux/Windows both have semaphores with a maximum count that can be realistically be described as 'Unlimited'.

Use James' suggestion on Windows - it will work fine. Init. your semaphore with zero count. Add a task to your big (thread-safe), container, then signal the semaphore. In the thread, wait on the semaphore, then get a task from your container and process it. You can pass the semaphore instance to multiple threads if you wish - that will work OK as well.

Rgds, Martin


Sounds like you want a Win32 kernel event. See CreateEvent.


WaitForSingleObject and CreateSemaphore?


Thanks all, thats my conclusion:

void ThreadPool::ThreadStartPoint(ThreadPool* tp)
{
    while (1)
    {    
        WaitForSingleObject(tp->m_taskCountSemaphore,INFINITE); // while (num of tasks==0) block; decreament num of tasks

        BaseTask* current_task = 0;

        // get top priority task
        EnterCriticalSection (&tp->m_mutex);
        {   
            current_task = tp->m_tasksQue.top();
            tp->m_tasksQue.pop();
        }
        LeaveCriticalSection (&tp->m_mutex);

        current_task->operator()(); // this is not critical section
        current_task->PostExec();
    }
}

void ThreadPool::AddTask(BaseTask& _task)
{
    EnterCriticalSection (&m_mutex);
    {
        m_tasksQue.push(&_task);
        _task.PrepareTask(m_mutex);
    }
    LeaveCriticalSection (&m_mutex);

    if (!ReleaseSemaphore(m_taskCountSemaphore,
                          1,    // increament num of tasks by 1
                          NULL  // don't store previuos num of tasks value
                          )) 
    {//if failed
        throw ("semaphore release failed");
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜