puts 'неправильна.'

end

13.1.5. Обработка исключений

Что произойдет, если в потоке возникнет исключение? Как выясняется, поведение можно сконфигурировать заранее.

Существует флаг abort_on_exception, который работает как на уровне класса, так и на уровне экземпляра. Он реализован в виде метода доступа (то есть позволяет читать и устанавливать атрибут) на обоих уровнях. Если abort_on_exception для некоторого потока равен true, то при возникновении в этом потоке исключения будут завершены и все остальные потоки.

Thread.abort_on_exception = true

t1 = Thread.new do

 puts 'Привет!'

 sleep 2

 raise 'some exception'

 puts 'Пока!'

end

t2 = Thread.new { sleep 100 }

sleep 2

puts 'Конец'

В этом примере флаг abort_on_exception установлен в true на уровне системы в целом (отменяя подразумеваемое по умолчанию значение). Следовательно, когда в потоке t1 возникает исключение, завершаются и t1, и главный поток. Печатается только слово «Привет!».

В следующем примере эффект такой же:

t1 = Thread.new do

 puts 'Привет!'

 sleep 2

 raise 'some exception'

 puts 'Пока!'

end

t1.abort_on_exception = true

t2 = Thread.new { sleep 100 }

sleep 2

puts 'Конец'

А вот в следующем оставлено принимаемое по умолчанию значение false, и мы наконец-то видим слово «Конец», печатаемое главным потоком (слова «Пока!» мы не увидим никогда, поскольку поток t1 при возникновении исключения завершается безусловно).

t1 = Thread.new do

 puts 'Привет!'

 sleep 2

 raise 'some exception'

 puts 'Пока!'

end

t2 = Thread.new { sleep 100 }

sleep 2

puts 'Конец'

# Выводится:

Привет!

Конец

13.1.6. Группы потоков

Группа потоков — это механизм управления логически связанными потоками. По умолчанию все потоки принадлежат группе Default (это константа класса). Но если создать новую группу, то в нее можно будет помещать потоки.

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

Метод класса ThreadGroup.new создает новую группу потоков, а метод экземпляра add помещает поток в группу.

f1 = Thread.new('file1') { |file| waitfor(file) }

f2 = Thread.new('file2') { |file| waitfor(file) }

file_threads = ThreadGroup.new

file_threads.add f1

file_threads.add f2

Метод экземпляра list возвращает массив всех потоков, принадлежащих данной группе.

# Подсчитать все 'живые' потоки в группе this_group.

count = 0

this_group.list.each {|x| count += 1 if x.alive? }

if count < this_group.list.size

 puts 'Некоторые потоки в группе this_group уже скончались.'

else

 puts 'Все потоки в группе this_group живы.'

end

В класс ThreadGroup можно добавить немало полезных методов. В примере ниже показаны методы для возобновления всех потоков, принадлежащих группе, для группового ожидания потоков (с помощью join) и для группового завершения потоков:

class ThreadGroup

def wakeup

 list.each { |t| t.wakeup }

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

0

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

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