Вход/Регистрация
Программирование на языке Ruby
вернуться

Фултон Хэл

Шрифт:

t2.alive?, # true

t2.stop?] # true

Получить состояние потока позволяет метод

status
. Он возвращает значение
"run"
, если поток выполняется;
"sleep"
— если он приостановлен, спит или ожидает результата ввода/вывода;
false
— если поток нормально завершился, и
nil
— если поток завершился в результате исключения.

t1 = Thread.new { loop {} }

t2 = Thread.new { sleep 5 }

t3 = Thread.new { Thread.stop }

t4 = Thread.new { Thread.exit }

t5 = Thread.new { raise "exception" }

s1 = t1.status # "run"

s2 = t2.status # "sleep"

s3 = t3.status # "sleep"

s4 = t4.status # false

s5 = t5.status # nil

Глобальную переменную

$SAFE
можно установить по-разному в разных потоках. Стало быть, она вовсе не является глобальной, но стоит ли жаловаться на это, если она позволяет разным потокам работать с разным уровнем безопасности? Метод
safe_level
возвращает текущий уровень безопасности потока.

t1 = Thread.new { $SAFE = 1; sleep 5 }

t2 = Thread.new { $SAFE = 3; sleep 5 }

sleep 1

lev0 = Thread.main.safe_level # 0

lev1 = t1.safe_level # 1

lev2 = t2.safe_level # 3

Метод доступа

priority
позволяет узнать и изменить приоритет потока:

t1 = Thread.new { loop { sleep 1 } }

t2 = Thread.new { loop { sleep 1 } }

t2.priority = 3 # Установить для потока t2 приоритет 3

p1 = t1.priority # 0

p2 = t2.priority # 3

Поток с большим приоритетом будет чаще получать процессорное время. Специальный метод

pass
позволяет передать управление планировщику. Иными словами, поток просто уступает свой временной квант, но не приостанавливается и не засыпает.

t1 = Thread.new do

 puts "alpha"

 Thread.pass

 puts "beta"

end

t2 = Thread.new do

 puts "gamma"

 puts "delta"

end

t1.join

t2.join

В этом искусственном примере вызов

Thread.pass
приводит к печати строк в следующем порядке:
alpha gamma delta beta
. Без него было бы напечатано
alpha beta gamma delta
. Конечно, этот механизм следует использовать не для синхронизации, а только для экономного расходования процессорного времени.

Выполнение приостановленного потока можно возобновить методами методами

run
или
wakeup
:

t1 = Thread.new do

 Thread.stop

 puts "Здесь есть изумруд."

end

t2 = Thread.new do

 Thread.stop

 puts "Вы находитесь в точке Y2."

end

sleep 1

t1.wakeup

t2.run

Между этими методами есть тонкое различие. Метод

wakeup
изменяет состояние потока, так что он становится готовым к выполнению, но не запускает его немедленно. Метод же
run
пробуждает поток и сразу же планирует его выполнение.

В данном случае

t1
просыпается раньше
t2
, но
t2
планируется первым, что приводит к следующему результату:

Вы находитесь в точке Y2.

Здесь есть изумруд.

Конечно, было бы неосмотрительно реализовывать синхронизацию на основе этого механизма.

Метод экземпляра

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

factorial1000 = Thread.new do

 begin

prod = 1

1.upto(1000) {|n| prod *= n }

puts "1000! = #{prod}"

 rescue

  • Читать дальше
  • 1
  • ...
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: