Мьютекс определенно то, что вы ищете. Если у каждого события есть свой мьютекс, я бы не стал беспокоиться о производительности; причина в том, что, если вы не добавляете много обработчиков во время обработки событий, маловероятно, что мьютекс будет спорить и замедлит вас.
Однако, если у вас есть несколько потоков, вызывающих метод operator() на том же объекте, этот мьютекс может быть проблемой. Но без этого, как вы обеспечите, чтобы ваши обратные вызовы были вызваны поточно-безопасным способом? (Я замечаю, что вы передаете целочисленную ссылку и возвращаете пустоту, поэтому я предполагаю, что это не повторные обработчики.)
EDIT: очень хороший вопрос в ваших комментариях. Честно говоря, я никогда не задумывался о том, было ли у мьютексов слишком много накладных расходов при синхронном использовании. Поэтому я собрал этот небольшой тест.
#include <stdio.h>
#include <pthread.h>
#define USE_PTHREAD_MUTEX 1
int main(int argc, char * argv[]) {
pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);
long useless_number = 0;
long counter;
for(counter = 0; counter < 100000000; counter++) {
#if USE_PTHREAD_MUTEX
pthread_mutex_lock(&mutex);
#endif
useless_number += rand();
#if USE_PTHREAD_MUTEX
pthread_mutex_unlock(&mutex);
#endif
}
printf("%ld\n", useless_number);
}
Я запустил это в своей системе и получил следующие промежутки времени.
С USE_PTHREAD_MUTEX 0 средняя продолжительность работы составляет 1,2 секунды.
С USE_PTHREAD_MUTEX 1 средняя продолжительность работы составляет 2,8 секунды.
Таким образом, чтобы ответить на ваш вопрос, определенно накладные расходы. Ваш пробег может отличаться. Кроме того, если несколько потоков конкурируют за доступ к ресурсу, больше времени будет потрачено на блокирование, обязательно. Кроме того, в чисто синхронном контексте, скорее всего, будет потрачено больше времени на доступ к общему ресурсу, чем до ожидания блокировки/разблокировки мьютекса. То есть накладные расходы самой логики мьютекса, вероятно, будут незначительными по сравнению с этими вещами.
Как часто они звонят в секунду? Почему этот же объект должен быть доступен для всех потоков? Разве они не могут просто отправить сообщение мьютекса, которое получено одним потоком? –