Что лучший способ состоит в том, чтобы ждать переменной в многопоточном применении

Я хотел бы сделать что-то как ниже для многопоточной программы:

// wait for variable to become true but don't hog resources  
// then re-sync queues  

Действительно ли что-то вроде этого - хорошее решение?

while (!ready) {
    Thread.Sleep(250); // pause for 1/4 second;
};

9
задан Alex B 13 January 2010 в 21:47
поделиться

8 ответов

Нет, это не хорошее решение. Сначала это может спать слишком долго. Второе, что темы легко попасть в LockStep. Вот пара ссылок на статьи MSDN в соответствующих методах синхронизации:

15
ответ дан 4 December 2019 в 09:13
поделиться

Вот как вы делаете это, используя усиление:

boost::condition_variable condvar;
boost::mutex mutex;
bool finished1 = false;
bool finished2 = false;

void longComputation1()
{
    {
        boost::lock_guard<boost::mutex> lock(mutex);
        finished1 = false;
    }
    // Perform long computation
    {
        boost::lock_guard<boost::mutex> lock(mutex);
        finished1 = true;
    }
    condvar.notify_one();
}

void longComputation2()
{
    {
        boost::lock_guard<boost::mutex> lock(mutex);
        finished2 = false;
    }
    // Perform long computation
    {
        boost::lock_guard<boost::mutex> lock(mutex);
        finished2 = true;
    }
    condvar.notify_one();
}

void somefunction()
{
    // Wait for long computations to finish without "spinning"
    boost::lock_guard<boost::mutex> lock(mutex);
    while(!finished1 && !finished2)
    {
        condvar.wait(lock);
    }

    // Computations are finished
}

ради краткости я не включал код нереста.

Усилие :: Lock_Guard использует Raii IDIOM для автоматического разблокировки Mutex, когда объект блокировки выходит из приспособления. Очень полезно для предотвращения тупиков в случае исключения.

Я нахожу переменные условия меньше ошибок, подверженных ошибкам, чем объекты мероприятия Microsoft. Если вы используете Boost.Thread, вы получите дополнительное преимущество кроссплатформенной питье.

5
ответ дан 4 December 2019 в 09:13
поделиться

Код выше будет работать, и, возможно, целесообразно в некоторых обстоятельствах.

Вы также можете посмотреть на критический раздел или семафоре - это сделает ваш прикладной блок и дождается, пока ресурс не станет доступен,

Ваш поток, который выполняет работу Mutex, имеет некоторую работу, тем временем основной метод Также пытается схватить то же Mutex, но не может. Когда работник нить (ы) выходит, они отпускают Mutex, и ваша основная нить может пройти критический раздел и продолжить.

1
ответ дан 4 December 2019 в 09:13
поделиться

Прежде всего, вам нужно объявить вашу «готовую» переменную по крайней мере «волатильный» или это может иметь неприятные побочные эффекты. Во-вторых, сон , что давно повторно пообередование условия, является лишь хорошей идеей, если продолжительность это может потребоваться, действительно очень долго, скажем несколько минут.

Использование функций события WinAPI ( CreateeeVent, SetEvent (), WiforForsingleEvent () ) - лучший способ сделать это. Конечно, он представляет некоторые накладные расходы, но обычно это нормально.

Если вы хотите придерживаться своего решения, зацикливаться и перепроверять условие несколько раз, прежде чем снова спать, может улучшить производительность в некоторых сценариях.

0
ответ дан 4 December 2019 в 09:13
поделиться

необработанный Win32, API имеет СОБЫТИЕ для того, чтобы сделать это, вот пример использования:

http://msdn.microsoft.com/en-us/library/ms686915 (По сравнению с 85) .aspx

Однако, что API является C-oriented и особый к Windows. При записи программы C++ вы могли бы считать создание вашего кода более независимым от платформы при помощи чего-то как повышение:: потоки, который имеет аналог в Условия .

протест А, который я нашел, состоит в том, что Windows может WaitForMultipleObjects, таким образом ожидающий на нескольких событиях (и другие классы дескриптора) за один раз. повышение не имеет никакого параллельного AFAIK.

0
ответ дан 4 December 2019 в 09:13
поделиться

Предоставлено, это C #, но я нашел эту книгу, чтобы быть чрезвычайно полезной для разработки мультипоток.

http://www.albahari.com/threading/

Некоторые из информации не относятся к языку.

-2
ответ дан 4 December 2019 в 09:13
поделиться

На верхней части хороших ответов уже предоставлено - вы будете тратить половину времени сна, при условии случайного распределения возникновения, которое вы хотите обнаружить. 125 мс - это вечность в компьютере.

WAITFOSSINGLEOBJECT на ручке события Win32 позволяет обнаруживать требуемый сигнал псевдо-немедленно (в зависимости от того, какие другие темы в вашем процессе делают), и не делать избыточные проверки (сколько ненужных петель вы должны выполнить перед сигналом Прибудет?), предоставил установку потокового вызова Setevent, когда это будет сделано с его работой. Бул тогда избыточный, который так, как должно быть.

0
ответ дан 4 December 2019 в 09:13
поделиться

Попробуйте использовать событие (объект ядра) вместо простой переменной и замените свой цикл:

WaitForSingleObject(hEventHandle, INFINITE);
4
ответ дан 4 December 2019 в 09:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: