Итак, ситуация в этом. У меня есть библиотека C++, которая выполняет некоторую межпроцессную связь, с функцией wait()
, которая блокирует и ждет входящего сообщения. Трудность в том, что мне нужен приуроченный wait, который будет возвращаться со статусом, если в течение определенного времени не получено сообщение.Как реализовать временное ожидание блокирующего вызова?
Самое элегантное решение - это, вероятно, переписать библиотеку, чтобы добавить время ожидания к ее API, но, ради этого вопроса, я предполагаю, что это невозможно. (В действительности, это выглядит сложно, поэтому я хочу знать, что другой вариант.)
Вот как я хотел бы сделать это с напряженным циклом ожидания, в псевдокоде:
while(message == false && current_time - start_time < timeout)
{
if (Listener.new_message()) then message = true;
}
Я не» t хочу ожидание ожидания, которое ест процессорные циклы. И я также не хочу просто добавлять вызов sleep()
в цикле, чтобы избежать загрузки процессора, поскольку это означает более медленный ответ. Я хочу что-то, что делает это с надлежащим видом блоков и прерываний. Если лучшее решение включает в себя потоки (что кажется вероятным), мы уже используем boost::thread
, поэтому я бы предпочел использовать это.
Я отправляю этот вопрос, потому что это похоже на ситуацию, в которой будет правильный ответ «лучших практик», поскольку это довольно распространенный шаблон. Каков правильный способ сделать это?
Редактировать добавить: Большая часть моей озабоченности здесь заключается в том, что это именно то место в программе, которое критично и критично критично, чтобы избежать условий гонки или утечек памяти. Таким образом, хотя «использовать два потока и таймер» является полезным советом, я все еще не могу понять, как реально реализовать это безопасным и правильным способом, и я легко вижу, как я делаю ошибки в новинке в коде, который я даже не знаю, что я сделал. Таким образом, некоторый фактический пример кода был бы действительно оценен!
Кроме того, я беспокоюсь о решении с несколькими потоками: если я использую метод «поместить вызов блокировки во втором потоке и выполнить метод« время ожидания по этому потоку », что произойдет с этим вторым потоком, если заблокированный вызов никогда не возвращается? Я знаю, что время ожидания в первом потоке вернется, и я увижу, что ответа нет, и продолжайте с вещами, но разве я тогда просочился в поток, который будет сидеть в заблокированном состоянии навсегда? Есть ли способ избежать этого? (Есть ли способ избежать этого и избежать утечки памяти второго потока?). Полное решение того, что мне нужно, должно было бы избежать утечки, если вызов блокировки не вернется.
Спасибо! Я думаю, это звучит так, как хотелось бы, но у меня недостаточно информации, чтобы понять, как это сделать. В частности, я не знаю, как правильно установить сигнал, который прервет блокирующий вызов и навсегда остановит его, а не вернется к нему после выхода из обработчика прерываний. Не могли бы вы добавить немного объяснений о том, как это сделать? –
Из ссылки GNU в моем ответе: «Чтобы иметь возможность использовать функцию тревоги для прерывания системного вызова, который может блокироваться иначе неопределенно, важно не устанавливать флаг SA_RESTART при регистрации обработчика сигнала с использованием sigaction». Я бы попробовал это. Тогда возникает вопрос, что делает код библиотеки, когда его примитивные операции возвращают EINTR. Если вам повезет, библиотека, которую вы используете, будет иметь некоторую функцию «остановки», которую вы можете вызывать из обработчика сигнала, или она просто вернется из блокирующего вызова в EINTR. Если он более настойчив и снова блокирует EINTR, жизнь становится сложнее. –
Хорошо, это начинает иметь смысл - я пропустил эту линию, а также не понял, что существует SA_RESTART, или что-либо может случиться с прерванным кодом, кроме того, что он продолжается, когда он остановился. Спасибо что подметил это! (Я не уверен, что делает код библиотеки в этом случае или насколько мы можем полагаться на это, так как у него есть крючки для людей, чтобы добавить другой код на этом уровне для разных коммуникационных библиотек, но я узнаю.) –