Использовать мьютекс в качестве семафора?

Мне нужны два потока для выполнения "тик-такта" . При имплантации с семафором это выглядит нормально:

Semaphore tick_sem(1);
Semaphore tock_sem(0);

void ticker( void )
{
   while( true )
   {
      P( tick_sem );
      do_tick();
      V( tock_sem );
   }
}

void tocker( void )
{
   while( true )
   {
      P( tock_sem );
      do_tock();
      V( tick_sem );
   }
}

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

std::mutex tick_mutex;
std::mutex tock_mutex;
tock_mutex.lock();

void ticker( void )
{
   while( true )
   {
      tick_mutex.lock();
      do_tick();
      tock_mutex.unlock();
   }
}

void tocker( void )
{
   while( true )
   {
      tock_mutex.lock()
      do_tock();
      tick_mutex.unlock();
   }
}

Я думаю, что это запах мьютекса. не предназначен для передачи информации другому потоку. (Стандартный комитет С ++ 11 добавил ложную ошибку try_lock для предотвращения неожиданной передачи информации; §30.4.1 / 14.) Похоже, что мьютексы предназначены для синхронизации доступа к переменной, которая затем может передавать информацию в другой поток.

Наконец, при реализации с std :: condition_variable он выглядит правильно, но более сложный (переменная tick_vs_tock, мьютекс и переменная условия). Я опустил реализацию для краткости, но она действительно прямолинейна.

Подходит ли решение мьютекса? Или с этим что-то не так?

Есть ли хороший шаблон для решения моей проблемы с тик-тактом, о котором я не думал?

13
задан deft_code 26 November 2012 в 20:41
поделиться