2015-10-14 5 views
0

У меня очень важная задача в моей основной теме. Тем не менее, я также хотел бы одновременно напечатать некоторую информацию об этой задаче.cout on extra thread - thread safety

Задача: cout занимает некоторое время для выполнения и, следовательно, замедляет задачу, чувствительную к времени, в основном потоке.

Idea: Я думал о создании дополнительного потока, который обрабатывает выходные данные. Для связи между основным потоком и вновь созданным потоком я думал о векторе, который включает строки, которые должны быть напечатаны. Во вновь созданном потоке бесконечный цикл while будет печатать эти строки один за другим.

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

Вопрос: Есть ли альтернатива блокировке/разблокировке вектора? Я беспокоюсь о том, что блокировка вектора ошибочна? Не могли бы вы принять совершенно другой подход к решению проблемы?

+1

Вам следует попробовать блокировать и разблокировать, чтобы проверить, действительно ли это узкое место в вашем приложении. А может и не быть. В противном случае рассмотрите блокированные структуры данных, такие как [boost :: lockfree :: queue] (http://www.boost.org/doc/libs/1_59_0/doc/html/boost/lockfree/queue.html) или [ повышение :: lockfree :: spsc_queue] (http://www.boost.org/doc/libs/1_59_0/doc/html/boost/lockfree/spsc_queue.html). – crayzeewulf

+0

Эти блокирующие данные выглядят многообещающими. Я не знал, что у boost были такие структуры данных очереди. Я буду реализовывать их завтра! Спасибо за вашу поддержку. – chrisp

ответ

1

В зависимости от того, как зависит от времени задача, я бы, вероятно, создал вектор выходов в потоке производителя, а затем передал весь вектор в потребительский поток (и повторял по мере необходимости).

Очередь между двумя должна быть потокобезопасной, но вы можете сохранить накладную мелочь, передав вектор каждые, скажем, 50-100 мс или около того. Это по-прежнему достаточно коротким, чтобы выглядеть как в режиме реального времени большинству наблюдателей, но достаточно долго, чтобы в большинстве случаев держать слишком узкие места для блокировки.

+0

Отличная идея минимизировать количество времени, которое нужно заблокировать. Будет использовать этот пост в крайнем случае, если ни одно из других решений не будет работать для меня. – chrisp

1

Вы можете использовать идею, которую часто видят в программировании «прерывания» - отправлять данные из потока в кольцевой буфер. Затем в другом потоке печатайте из кольцевого буфера. Фактически, в «старые добрые времена» можно было написать кольцевой буфер без каких-либо «атомических» (и все еще можно делать на некоторых встроенных системах).

Но даже с атоматикой кольцевые буферы не сложны для записи. Существует одна реализация здесь: c++ threadsafe ringbuffer implementation (непроверенный, но на первый взгляд кажется ОК).

+0

Кажется, отличная идея. Однако я попробую тщательно протестированные решения, такие как блокированные очереди в ускорительной библиотеке. +1 тем не менее, спасибо за вашу помощь! :) – chrisp