Да, вы должны добавить некоторую защиту в ваш код.Вам не нужно ничего экзотического, вы хотите получить доступ к ресурсу (вашему потоку), пока он может использоваться чем-то другим.Два типа объектов синхронизации хорошо справляются с этой задачей: Критические секции и Mutex.Для получения более подробной информации о замках вы можете начать читать эту статью в Википедии . Mutex обычно медленнее, но может использоваться несколькими процессами, это не ваш случай, поэтому вы можете использовать простой критический раздел для синхронизации ваших потоков.
Несколько советов, есливы не планируете использовать библиотеку третьей части (как, например, отличный Boost).
Когда EnterCriticalSection функция для получения блокировки.Если ресурс заблокирован кем-то другим, ваш поток будет приостановлен и повторно активирован, когда ресурс будет освобожден его владельцем (более того, ваш заблокированный поток может повысить его приоритет). Для кратковременных блокировок это не может быть оптимальным решением , потому что приостановка / возобновление потока требует много времени и ресурсов.По этой причине вы можете установить spin ;перед приостановкой вашего потока ОС будет тратить немного времени, ничего не делая в этом потоке, это может дать время для блокировки владельца, чтобы завершить свою работу и освободить поток.Чтобы использовать это, вы должны инициализировать ваш критический раздел с InitializeCriticalSectionAndSpinCount вместо InitializeCriticalSection .
Если вы планируете использовать критический раздел, вы можете подумать, чтобы обернуть все необходимоев классе вы будете использовать переменную scope для всего, и ваш код будет более понятным (это всего лишь пример, истинная реализация не может быть такой наивной):
class critical_section
{
public:
critical_section()
{
// Here you may use InitializeCriticalSectionAndSpinCount
InitializeCriticalSection(&_cs);
// You may not need this behavior, anyway here when you create
// the object you acquire the lock too
EnterCriticalSection(&_cs);
}
~critical_section()
{
LeaveCriticalSection(&_cs);
DeleteCriticalSection(&cs);
}
private:
CRITICAL_SECTION _cs;
};
в Unix / Linux (или вы хотите быть переносимым) вам следует использовать функции pthread.h
для Mutex.
Блокировки может быть недостаточно
Это только первый шаг, если ваше приложение регистрируетЛот Вы можете замедлить все потоки, ожидающие регистрации (не делайте ничего априори, проверьте и профиль).Если это так, вы должны создать очередь, ваша logText()
функция просто помещает новый (предварительно отформатированный) элемент в очередь и вызывает PulseEvent , чтобы сообщить о событии (созданном с помощью CreateEvent ).У вас будет второй поток, ожидающий этого события с WaitForSingleObject , ваш поток проснется и извлечет элемент из очереди.Вам по-прежнему может понадобиться какой-то механизм блокировки (или вы можете написать собственную неблокирующую параллельную очередь , чтобы избежать какой-либо блокировки. Это решение быстрее и не использует никаких блокировок, но я думаю, что вам следует это сделатьчто-то подобное, только если вы хотите изучить тему (темы), обычно для простого требования к журналу вам не нужно добавлять такую сложность.