как вернуться с заблокированного звонка? - PullRequest
1 голос
/ 15 января 2010

возможно ли заставить поток вернуться из вызова функции блокировки, такой как блокировка чтения из потока?

int x;
std::cin >> x;

например ...

Ответы [ 4 ]

5 голосов
/ 15 января 2010

Нет, это невозможно. Если вы хотите узнать, есть ли данные для чтения, используйте системный вызов select () - если вы только читаете, когда есть данные, вы никогда не заблокируете

0 голосов
/ 15 января 2010

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

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

Решение, которое мы приняли, довольно простое и, конечно, включает в себя MT:

  • После получения запроса запустите таймер, который будет вызывать обратный вызов при завершении
  • Если вы успешно завершите работу, отключите таймер, теперь он не нужен.
  • Выполните свою обработку, и после каждого «заблокированного» вызова проверьте таймер (также с другими регулярными интервалами): если он был запущен, вы слишком долго и должны отказаться от обработки и вернуться со всей поспешностью. Ответ на запрос теперь отвечает другой поток, поскольку вы слишком долго.
  • Когда таймер срабатывает, начинайте новый поток с обратным вызовом, этот метод должен отвечать "наилучшим образом" и должен воздерживаться от использования заблокированных вызовов. Он может использовать спецификацию, используемую другим потоком, если упомянутая спецификация правильно обрабатывает MT (блокировка и т. Д.)

По привычке мы устанавливаем таймер в удобную зону в диапазоне от 75% до 95% от максимального времени, разрешенного для обработки запроса (настраивается по категории запросов).

Это позволяет вам аккуратно избегать блокирования вызовов. Если вы не хотите правильно синхронизировать свою спецификацию (так как это связано с накладными расходами), ответ «наилучшее усилие» вполне может быть простым сообщением о повторной попытке (это 95%). Если вам нужно выполнить очистку или другой способ (кеш?) Ответить, вам потребуется синхронизация как минимум в части спецификации (это 75%).

0 голосов
/ 15 января 2010

Вы можете посмотреть объект istream.

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

0 голосов
/ 15 января 2010

Возможно, попробуйте метод istream::readsome(). Он не ждет устройства и читает только то, что находится в буфере буферизованного потока.

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