2012-04-09 2 views
4

Я унаследовал некоторый код, как это:Нужно ли мне использовать мьютексы или блокировать при вызове функции ResetEvent()?

m_mutex.Lock(); 
ResetEvent(m_hSyncObject); 
m_mutex.Unlock(); 

Same для SetEvent()

ли эти Мьютексы необходимых в данном случае - делать эти вызовы ведут себя, или я могу уйти с удалением замков? Эта функция уже имела некоторые inc/decs значений, которые я сделал ранее, и теперь только эти события находятся в замках, поэтому избавление от них будет большим выигрышем, если это возможно.

+2

Вам не нужен дополнительный мьютекс – 0xC0000022L

ответ

2

Этот дополнительный мьютекс почти наверняка не нужен. Функции ResetEvent и SetEvent могут безопасно звонить из нескольких потоков.

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

+1

Уже все это. Профилер показал огромное количество звонков на «быстрые» блокировки. Система работы плохо злоупотребляла ими. Это были последние 2 функции, которые я не знал о блокировке. Теперь, просматривая код, как вы предлагаете, убедитесь, что все остальное, как и должно быть ... –

+0

«Профилер показал огромное количество звонков на« быстрые »блокировки» - о, дорогая: ((Сочувствую. –

1

События атомарные, так что нет никакой необходимости использовать семафор вокруг SetEvent или ResetEvent, если нет что-то еще вместе с ним и два должны быть сделаны атомарно (например, если вы установите одно событие и сброса другой).

+0

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

1

Предостережение программиста!

События с ручной перезагрузкой сложны в использовании и могут потребовать от вас блокировки вокруг настройки и сброса события (события автоматического сброса облегчают устранение этих проблем).

Рассмотрим этот код:

Worker() { 
    WaitForSingleObject(hEvent); 
    DoWork(); 
    ResetEvent(hEvent); 
} 

EventThread() { 
    QueueWork(); 
    SetEvent(hEvent); 
} 

Можно с колоритным перемежения для работника, чтобы сбросить событие после EventThread дал понять это, что заставит работника висеть, когда он ждет. Для правильного использования события ручного перезапуска в этом случае вам нужно будет получить блокировку вокруг события сброса и проверить состояние очереди с помощью сброса события.

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

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