2015-07-29 6 views
0

Устранение проблемы:std :: Thread занимает больше времени, чтобы пробудиться от ожидания на std :: condition_variable?

У меня есть потребительский поток производителей, совместно использующий общие данные, которые представляют собой не что иное, как структуру. Потребительский поток ожидает переменную std :: condition wait. потоки производителя возвращают пакет, записывающий общий struture и уведомляющий потребительский поток.

проблемы: потребительский поток должен обрабатывать и отправлять ответ с несколькими миллисекундами (скажем, 10-15 мс).

Проблема. В течение некоторого периода времени существует несколько случаев, когда сама ветка принимает время, чтобы проснуться от ожидания cv и, таким образом, не в состоянии отклик в течение нескольких мс.

Я попытался использовать доходность, но это заставляет процессор, и требование заключается в том, что использование процессора должно быть как можно меньше.

Я интересуюсь: 1 - Почему поток занимает столько времени, чтобы проснуться .. ?? (в некоторых случаях более 40 мс). 2 - Есть ли другой способ совместного использования данных между потоками, не позволяя нить спать, а также используя минимальный процессор. (Пробный канал, но снижает производительность по сравнению с текущей реализацией разделяемой памяти).

3 - предлагайте любой другой дизайн, который может не содержать темы, которые по-прежнему сохраняют проблемы отдельно и достигают необходимой задержки. ????

Это общие данные:

class Message 
{ 
    typedef std::basic_string<uint8_t> MesgBuffType; 
    MesgBuffType _buffer; 

    static uint16_t _data[256]; 
    public : 
    append(data .....,len) append methods 
} 

void ProcessData(Messege msg) 
{ 
    std::unique_lock<std::mutex> lock(mutex); 
    sharedData.set(msg); 

    lock.unlock(); 
    _syncCondVar.notify_one(); 
} 

void consumeData() 
{ 
    std::unique_lock<std::mutex> lock(mutex); 
    _syncCondVar.wait(lock); 
    Messege req; 
    if (sharedData.get(req)) 
    { 
     lock.unlock(); 
     processRequest(req); 
    } 
} 

Добавлено поддержку кода.

+0

Пожалуйста, не забывайте указать операционную систему и компилятор вы используете, –

+0

окружающую среду это Windows с VS2013. – VikramChopde

+0

Вы пытались переместить 'lock.unlock' после' notify_one'? –

ответ

3

1 - Почему нить занимает так много времени, чтобы проснуться .. ?? (в некоторых случаях более 40 мс).

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

2 - Есть ли другой способ совместного использования данных между потоками, не позволяя нить спать, а также используя минимальный процессор. (Пробная труба, но снижает производительность по сравнению с текущей реализацией общей памяти).

Использование атомных или незакрепленных конструкций, но их сложно использовать правильно.

3 - предлагайте любой другой дизайн, который может не содержать темы, которые по-прежнему сохраняют проблемы отдельно и достигают требуемой задержки. ????

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

+0

Jon - mutex выпускается непосредственно перед вызовом уведомления. мы перешли к нескольким потокам, потому что в одном потоке поток был занят обработкой пакета, в то время как новый пакет ожидал, что он будет выпущен. что вызвало большую задержку в обработке этого пакета. R u предлагая какой-то механизм асинхронного доступа, например, порты iocompleation и т. Д.? – VikramChopde

-1

Производитель в вашем коде разблокирует перед уведомлением. См. Do I have to acquire lock before calling condition_variable.notify_one()? по вопросу о выпуске фиксации/снятия блокировки.И см. Sync is unreliable using std::atomic and std::condition_variable для случая редкого случая, если вы не используете блокировку в своем продюсере. Прочитайте и оправдайте, хотите ли вы сохранить блокировку производителя или использовать блокировку для повышения производительности.

1

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

Переменные состояния являются апатридами: они не помнят пропущенные уведомления. Вы также можете получить побочные пробуждения. Вот почему некоторое состояние должно быть связано с переменными состояния, и ожидание должно выполняться в цикле, см. std::condition_variable::wait для получения более подробной информации.

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

Message global_message; 
unsigned global_message_update = 0; 

void ProcessData(Message const& msg) 
{ 
    std::unique_lock<std::mutex> lock(mutex); 

    global_message = msg; 
    ++global_message_update; 

    _syncCondVar.notify_one(); 
} 

void consumeData() 
{ 
    unsigned message_update = 0; 
    Messege req; 

    { 
     std::unique_lock<std::mutex> lock(mutex); 
     while(message_update == global_message_update) 
      _syncCondVar.wait(lock); 
     message_update = global_message_update; 
     req = global_message; 
    } 

    // now process req 
} 
+0

Maxim - время ожидания не является проблемой, если данные недоступны, поток должен ждать на cv, в тот момент, когда мы получаем данные, которые мы уведомляем, поэтому поток tht просыпается и обрабатывает данные ... в некоторых случаях это пробуждение требуется время. Processdata получает вызов только тогда, когда мы возвращаем полный пакет. – VikramChopde

+0

k .. получил ур комментарий .. u означает, что даже если данные доступны, мы сделаем поток спать .. и дождитесь уведомления .. вместо прямого получения данных и обработки. – VikramChopde

+0

@VikramChopde Да, вы поняли это правильно. Есть также побочные пробуждения. Подробнее см. Http://en.cppreference.com/w/cpp/thread/condition_variable. –

 Смежные вопросы

  • Нет связанных вопросов^_^