Когда блокировки мьютекса недостаточно?

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

Было 2 проблемы:

  • искаженный текст
  • изменение цвета мешает / не вовремя

Когда я добавил блокировку мьютекса в раздел, который изменяет цвет консоли и записывает в консоль, это помогло с замятым текстом (не видел его с момента блокировки мьютекса), но цвет консоли все еще неправильный.

Так что мьютекса недостаточно! Теперь я думаю, что мне понадобится очередь и единственный поток, который ожидает в этой очереди и сбрасывает ее, когда в ней есть что-то. Итак, мой вопрос: как определить, достаточно ли блокировки мьютекса? Как только задействованы каналы / файлы / связь с другим процессом?


person bobobobo    schedule 05.06.2011    source источник
comment
Из вашего описания проблемы действительно сложно что-либо сказать. Блокировок обычно бывает достаточно, потому что они изолируют транзакции, которые производят атомарные модификации.   -  person Diego Sevilla    schedule 05.06.2011
comment
Он читается, как у вас есть два мьютекса или неправильно объединяет изменение цвета и запись в одну заблокированную операцию.   -  person Steve-o    schedule 05.06.2011
comment
Похоже, что ваши функции изменяют глобальное состояние (цвет консоли), а затем предполагают, что глобальное состояние остается действительным даже после того, как они освобождают мьютекс.   -  person Travis Gockel    schedule 05.06.2011
comment
можете ли вы выделить соответствующий код, который меняет цвета, и создать более простую программу, которая показывает ошибку?   -  person Andrei    schedule 05.06.2011
comment
Мне непонятно, что вы имеете в виду под недостаточно. Еще мьютексы? Блокировка с большей областью видимости? Что-то другое? Вопрос довольно расплывчатый.   -  person Sam Miller    schedule 05.06.2011
comment
Под «недостаточно» я подразумеваю необходимость создания очереди (сообщений журнала), которая удаляется только одним потоком. Очередь сделана потокобезопасной, и у нас есть хороший контроль с мьютексом над записью в память.   -  person bobobobo    schedule 05.06.2011
comment
При правильном использовании мьютекса будет достаточно. Предложение Андрея хорошее.   -  person Nemo    schedule 05.06.2011
comment
Да, проблема не в мьютексе, а в вашей реализации.   -  person Ed S.    schedule 05.06.2011
comment
Это определенно звучит так, будто вы неправильно используете мьютекс; ваша атомарная операция (то, что окружено мьютексом) должна содержать как изменение цвета, так и запись текста, иначе нет никаких гарантий того, как они будут синхронизированы. Было бы неплохо, если бы вы разместили код и четкий пример того, что вы ожидаете увидеть и что на самом деле происходит.   -  person Sumudu Fernando    schedule 06.06.2011


Ответы (1)


Мьютекс (например, мьютекс boost / pthread) гарантирует эксклюзивный доступ к общему ресурсу между разными потоками (но не процессами, для этого вам понадобится именованный семафор).

Похоже, ваш общий ресурс - это доступ к терминалу. Тот факт, что вы блокируете его при изменении цвета, не означает, что он будет заблокирован, когда вы решите изменить цвет. Оба потока блокируют мьютекс перед записью в терминал или изменением цвета. В создании двух мьютексов нет необходимости, поскольку вы по-прежнему защищаете один общий ресурс (терминал).

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

person s1n    schedule 05.06.2011