Условные переменные (c / c ++ на windows xp) - PullRequest
2 голосов
/ 11 июня 2011

Я хочу написать поток, который запускает задачи из контейнера задач неограниченного размера.

Пока список задач пуст, поток, пытающийся получить задачу, должен быть заблокирован.

Исходя из Linux, я хотел использовать условную переменную, которая будет сигнализироваться при добавлении задачи и будет ждать, пока список пуст.

Я обнаружил, что CONDITION_VARIABLE доступен только из Windows Vista, поэтому об этом не может быть и речи,Семафоры также проблематичны из-за ограничения неограниченного размера.

Есть ли подходящее замещение?

Спасибо

Ответы [ 4 ]

1 голос
/ 11 июня 2011

Почему вы говорите, что семафоры проблематичны? В Linux / Windows есть семафоры с максимальным числом, которое можно реально описать как «Неограниченный».

Используйте предложение Джеймса для Windows - оно будет работать нормально. В этом. ваш семафор с нулевым счетом. Добавьте задачу в свой большой (потокобезопасный) контейнер, затем подайте сигнал семафору. В потоке дождитесь семафора, затем получите задачу из вашего контейнера и обработайте ее. Вы можете передать экземпляр семафора нескольким потокам, если хотите - это также будет работать нормально.

Rgds, Martin

1 голос
/ 11 июня 2011

Звучит так, будто вы хотите событие ядра Win32. См. CreateEvent.

0 голосов
/ 12 июня 2011

Спасибо всем, вот мой вывод:

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 голосов
/ 11 июня 2011

WaitForSingleObject и CreateSemaphore?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...