Как я могу избежать условных издержек, меняя указатели по окончании очереди потребителя-производителя? - PullRequest
1 голос
/ 10 декабря 2011

У меня есть класс logger с tbb :: concurrent_queue в качестве поля члена.Потоки, использующие объект logger, вызывают метод для отправки сообщения в эту внутреннюю очередь.Регистратор имеет внутренний поток, который потребляет эти сообщения, пока не получит сторожевое сообщение, а затем этот внутренний поток не завершится.Дело в том, что, если клиенты этого объекта logger пытаются зарегистрировать больше сообщений в этот регистратор (после того, как вызов shutdown отправил стражу), сообщения передаются в очередь, но никогда не принимаются на другом конце и незаметно теряются.В идеале я хотел бы уведомить, когда это так, но использование флага, установленного внутренним потребительским потоком при выходе, чтобы проверять каждый раз, когда я собираюсь отправить новое сообщение в очередь, добавило бы стоимость перехода к тому, что является для меня критическим путем.

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

то есть вызов: m_buffer-> push (message), где m_buffer - указатель на tbb :: concurrent_queue, должен после того, как поток потребителя завершится, по-прежнему выглядеть как m_buffer-> push (message), за исключением егоуходит куда-то еще ... мой собственный обработчик или около того ...

Как я могу это сделать?Я не могу поменять местами m_buffer, чтобы он указывал на любой другой пользовательский класс, если я не наследую от tbb :: concurrent_queue ... есть ли другой способ обойти это?

Спасибо

Ответы [ 2 ]

1 голос
/ 10 декабря 2011

Для меня это больше похоже на проблему дизайна.Чего хотят клиенты регистратора?Записать сообщение.Им все равно, идет ли речь о очереди, или записывается на экран, или записывается на листе бумаги, вставляется в стеклянную бутылку и выбрасывается в океан.

Так что ваш регистратор нуженвыставлять только метод log(), больше ничего.Перестановка очереди будет происходить изнутри, сохраняя две очереди в массиве и атомарно переключая указатель или индекс.

Кроме того, если скорость вашего кода журналирования критична, возможно, вы делаете это слишком много.

0 голосов
/ 10 декабря 2011

Зачем потоку журналирования устанавливать флаг «больше не регистрировать»? Метод 'shutdown' в логгере должен установить его таким образом, чтобы больше сообщений не помещалось в очередь, непосредственно перед тем, как он выдает страж, который в конечном итоге будет сигнализировать о завершении потока, так что страж всегда будет последним в очереди. То, что вы делаете с регистрацией запросов, когда установлен флаг, зависит от вашего регистратора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...