# С другой стороны, присваивание создает новый объект,

 # поэтому 'сокращение' становится бесполезным...

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

 puts 'beta'

end

t2 = Thread.new do

 puts 'gamma'

 puts 'delta'

end

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

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

Отметить Добавить цитату