Без опроса, есть ли способ для другого потока «сбросить» таймер спящего потока, заставляя его спать дольше? - PullRequest
0 голосов
/ 16 января 2020

Предположим, у нас есть два потока, A и B. B периодически выполняет какое-то действие, и A переводится в спящий режим до определенного времени. Я хочу, чтобы B мог вызывать функцию keepSleeping(A), что приведет к расширению таймера сна А. Если keepSleeping(A) не вызывается, A должен в конечном итоге проснуться.

При Linux, есть ли способ реализовать это без периодического пробуждения A, чтобы проверить, keepSleeping был вызван?

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

Ответы [ 2 ]

0 голосов
/ 16 января 2020

Без опроса, есть ли способ для другого потока «сбросить» таймер спящего потока, заставляя его дольше спать?

Если вы говорите о Thread.sleep, тогда выхода нет. Если A вызывает Thread.sleep(timeout), он не проснется, пока не истечет время ожидания. Вы можете разбудить его раньше, прерывая поток. Но вы не можете сделать так, чтобы не просыпался до тех пор, пока не будет позже.

Вы могли бы потенциально уменьшить количество нежелательных пробуждений потока с помощью использования wait / notify и реализации единый поток "менеджер сна" для выполнения уведомлений. Менеджер может использовать время ожидания или сна, чтобы дождаться следующего, что ему нужно сделать.

Предостережения:

  • В вашем сценарии он может проснуться и найти что ему ничего не нужно делать.

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

Если вы используете прерывания, подобные этому, вы должны быть уверены, что они не мешают (потенциально) другому использованию прерываний. Это добавляет сложности.

Стоит ли сложность? (IMO), только если вам нужно часто менять время пробуждения.

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

0 голосов
/ 16 января 2020

Не напрямую, нет. Если поток A вызвал sleep() или usleep() или подобное, то он проснется в назначенное время, и другой поток ничего не может сделать, чтобы остановить его. Конечно, вы можете сразу же вернуть нить A go обратно в спящий режим, если хотите, так что это не должно иметь большого значения.

Тем не менее, если вы не хотите, чтобы нить A просыпалась в все (кроме случаев, когда B хочет этого), тогда способ получить такое поведение состоял бы в том, чтобы иметь блок потока A для условной переменной вместо внутри sleep() вызова. В этой схеме поток A будет оставаться спящим бесконечно, пока поток B не подаст сигнал условной переменной, и в этот момент поток A проснется, сделает свое дело и снова заблокирует переменную условия. Это позволило бы потоку B получить полный контроль над тем, когда и если поток A проснется.

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