Я хотел бы передать строковый аргумент в дочерний поток (который постоянно читает сокет) и вызвать 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;
}
}
Для меня самым простым было бы:
Добавьте мьютекс в глобальное пространство имен, заблокируйте его, когда new_arg
доступно в родительском потоке и разблокировать его из дочернего потока.
использовать std::atomic<bool>
и использовать его так же, как в 1.
Однако чего-то, чего я хотел бы добиться, — это сделать ребенка прерываемым, чтобы я мог устранить if
-структура с конца while(){...}
блок. Я бы не отказался от штрафа за переключение контекста, потому что это событие было бы так редко.
Я относительно новичок в C ++, и я хотел бы узнать о лучших практиках здесь, как добиться этого эффективным способом. Я хотел бы решить эту проблему без использования Boost, единственные примеры, которые я смог найти для достижения прерывистых потоков, — это использование Boost.
Основное замечание о евангелизации 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.
Других решений пока нет …