Как эффективно передать аргумент, который встречается очень редко, дочернему потоку?

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

Я использую сокеты ZeroMQ, поэтому звоню setsockopt() является не поточно здесь я бы назвал setsockopt() из дочернего потока (как было рекомендовано Вот ). Обновление аргумента может происходить, вероятно, только один раз в миллиардах циклов чтения, и кажется немного неправильным добавлять if-структура для каждого цикла ребенка, как это:

bool new_arg_available;
std::string new_arg;

while(1){
sub_socket->recv(data);   // . . . . . . a blocking method call
printData(data)

...                       // . . . . . . data can set new_arg_available

if (new_arg_available){   // . . . . . . synchronization goes here
sub_socket->setsockopt(ZMQ_SUBSCRIBE, new_arg, ... );
new_arg_available = false;
}
}

Для меня самым простым было бы:

  1. Добавьте мьютекс в глобальное пространство имен, заблокируйте его, когда new_arg доступно в родительском потоке и разблокировать его из дочернего потока.

  2. использовать std::atomic<bool> и использовать его так же, как в 1.

Однако чего-то, чего я хотел бы добиться, — это сделать ребенка прерываемым, чтобы я мог устранить if-структура с конца while(){...} блок. Я бы не отказался от штрафа за переключение контекста, потому что это событие было бы так редко.

Я относительно новичок в C ++, и я хотел бы узнать о лучших практиках здесь, как добиться этого эффективным способом. Я хотел бы решить эту проблему без использования Boost, единственные примеры, которые я смог найти для достижения прерывистых потоков, — это использование Boost.

3

Решение

Добро пожаловать в страну Zen-of-Zero

Основное замечание о евангелизации ZeroMQ заключается в том, что авторы ZeroMQ с тех пор избегать какого-либо обмена — Нулевой обмена.

Учитывая, что вы уже создали экземпляр инфраструктуры ZeroMQ, лучше использовать межпотоковый PUSH/PULL через IO-поток без inproc:// Транспортный класс и забудьте о любой хитрой (b-) блокировке.

Одна сторона (Инжектор) просто aPushCHANNEL.send( new_arg );
а другой (Исполнитель) просто либо aPullCHANNEL.recv()-с при необходимости / при необходимости, или может использовать более разумные средства aPullCHANNEL.poll()-проверка, опять же лучше всего, если использовать форму опроса Zero-wait if aPullCHANNEL.poll( 0 ){...}else{...}

И ваш архитектура становится полностью разложенной, основанной на ролях, чистой и умной, на основе ролей, без каких-либо грязных тупиков (поэтому лучше забыть REQ/REP с начала), без каких-либо трудных для отслеживания / отладки концептуальных недостатков, и все ошибки обнаруживаются там, где это применимо и где местная ответственность имеет смысл отобразить первопричину любой такой ошибки для оперативной обработки ошибок.


NB: Да, с тех пор ZeroMQ разрабатывался без необходимости обеспечения безопасности потоков, поскольку не было ничего общего для совместного использования (совместное использование нулей). Некоторые недавние усилия в API v4.1 + начали отклоняться от этого Zen-of-Zero, так что можно прочитать о некоторых аспектах безопасности потоков, но, как отмечалось выше, и присутствовать почти на каждой странице невероятного ZeroMQ Pieter HINTJENS ‘. Библейская книга — «Код подключен, том 1«- лучше ничего не делиться.

Конструкция ZeroMQ полностью асинхронна и не требует ухода за блокировками, мьютекс-гимнастикой и другими формами внешних элементов в иначе чистых и интеллектуальных многоагентных асинхронных сигналах / сообщениях на основе архитектура. Вы влюбитесь в него, поэтому продолжайте пробовать и читайте книгу. Это будет трудно, но заплатит много за тех, кто продолжит и найдет красоту ZeroMQ Zen-of-Zero.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]