Программирование на языке Ruby
Шрифт:
thread = Thread.new do
t = Thread.current
x = "nXxeQPdMdxiBAxh"
t[:my_message] = x
x.reverse!
x.delete! "x"
x.gsub!(/[A-Z]/,"")
# С другой стороны, присваивание создает новый объект,
# поэтому "сокращение" становится бесполезным...
end
а = thread[:my_message] # "hidden"
Ясно, что сокращение не будет работать и в том случае, когда вы имеете дело с объектами наподобие
Fixnum
, которые хранятся как непосредственные значения, а не ссылки. 13.1.3. Опрос и изменение состояния потока
В классе
Thread
есть несколько полезных методов класса. Метод list
возвращает массив «живых» потоков, метод main
возвращает ссылку на главный поток программы, который породил все остальные, а метод current
позволяет потоку идентифицировать самого себя.
t1 = Thread.new { sleep 100 }
t2 = Thread.new do
if Thread.current == Thread.main
puts "Это главный поток." # HE печатается,
end
1.upto(1000) { sleep 0.1 }
end
count = Thread.list.size # 3
if Thread.list.include ?(Thread.main)
puts "Главный поток жив." # Печатается всегда!
end
if Thread.current == Thread.main
puts "Я главный поток." # Здесь печатается...
end
Методы
exit
, pass
, start
, stop
и kill
служат для управления выполнением потоков (как изнутри, так и извне):
# в главном потоке...
Thread.kill(t1) # Завершить этот поток.
Thread.pass # Передать управление t2.
t3 = Thread.new do
sleep 20
Thread.exit # Выйти из потока.
puts "Так не бывает!" # Никогда не выполняется.
end
Thread.kill(t2) # Завершить t2.
# Выйти из главного потока (все остальные тоже завершаются).
Thread.exit
Отметим, что не существует метода экземпляра
stop
, поэтому поток может приостановить собственное выполнение, но не выполнение другого потока. Существуют различные методы для опроса состояния потока. Метод экземпляра
alive?
сообщает, является ли данный поток «живым» (не завершил выполнение), а метод stop?
— находится ли он в состоянии «приостановлен».
count = 0
t1 = Thread.new { loop { count += 1 } }
t2 = Thread.new { Thread.stop }
sleep 1
flags = [t1.alive?, # true
t1.stop?, # false
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
Поделиться:
Популярные книги
Лейб-хирург
2. Зауряд-врач
Фантастика:
альтернативная история
7.34
рейтинг книги
Убивать чтобы жить 5
5. УЧЖ
Фантастика:
боевая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Обрыв
Проза:
классическая проза
русская классическая проза
8.93
рейтинг книги
Телохранитель Генсека. Том 1
1. Медведев
Фантастика:
попаданцы
альтернативная история
7.00
рейтинг книги
Дважды одаренный. Том II
2. Дважды одаренный
Фантастика:
городское фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Алые перья стрел
Детские:
детские приключения
8.58
рейтинг книги
Андер Арес
1. Андер Арес
Фантастика:
рпг
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Газлайтер. Том 26
26. История Телепата
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Инкарнатор
1. Стеллар
Фантастика:
боевая фантастика
рпг
7.30
рейтинг книги
Черный Маг Императора 17
17. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Страж Тысячемирья
5. Страж
Фантастика:
боевая фантастика
альтернативная история
фэнтези
5.00
рейтинг книги
Газлайтер. Том 5
5. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Назад в СССР 5
5. Курсант
Фантастика:
попаданцы
альтернативная история
6.64
рейтинг книги
Наследник для дона мафии
2. Наследники мафии
Любовные романы:
остросюжетные любовные романы
эро литература
5.00