Программирование на языке Ruby
Программирование на языке Ruby читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
В следующем примере эффект такой же:
t1 = Thread.new do puts "Привет!" sleep 2 raise "some exception" puts "Пока!"endt1.abort_on_exception = truet2 = Thread.new { sleep 100 }sleep 2puts "Конец"А вот в следующем оставлено принимаемое по умолчанию значение
falset1t1 = Thread.new do puts "Привет!" sleep 2 raise "some exception" puts "Пока!"endt2 = Thread.new { sleep 100 }sleep 2puts "Конец"# Выводится:Привет!Конец13.1.6. Группы потоков
Группа потоков — это механизм управления логически связанными потоками. По умолчанию все потоки принадлежат группе
DefaultВ любой момент времени поток может принадлежать только одной группе. Если поток помещается в группу, то он автоматически удаляется из той группы, которой принадлежал ранее.
Метод класса
ThreadGroup.newaddf1 = Thread.new("file1") { |file| waitfor(file) }f2 = Thread.new("file2") { |file| waitfor(file) }file_threads = ThreadGroup.newfile_threads.add f1file_threads.add f2Метод экземпляра
list# Подсчитать все "живые" потоки в группе this_group.count = 0this_group.list.each {|x| count += 1 if x.alive? }if count < this_group.list.size puts "Некоторые потоки в группе this_group уже скончались."else puts "Все потоки в группе this_group живы."endВ класс
ThreadGroupjoinclass ThreadGroupdef wakeup list.each { |t| t.wakeup }enddef join list.each { |t| t.join if t != Thread.current }enddef kill list.each { |t| t.kill }endend13.2. Синхронизация потоков
Почему необходима синхронизация? Потому что из-за «чередования» операций доступ к переменным и другим сущностям может осуществляться в порядке, который не удается установить путем чтения исходного текста отдельных потоков. Два и более потоков, обращающихся к одной и той же переменной, могут взаимодействовать между собой непредвиденными способами, и отлаживать такую программу очень трудно.
Рассмотрим простой пример:
x = 0t1 = Thread.new do 1.upto(1000) do x = x + 1 endendt2 = Thread.new do 1.upto(1000) do x = x + 1 endendt1.joint2.joinputs xСначала переменная
xНо фактический результат противоречит логике. На конкретной машине было напечатано значение 1044. В чем дело?
Мы предполагали, что инкремент целого числа — атомарная (неделимая) операция. Но это не так. Рассмотрим последовательность выполнения приведенной выше программы. Поместим поток
t1t2xt1 t2-------------------------- -----------------------------Прочитать значение x (123) Прочитать значение x (123)Увеличить значение на 1 (124) Увеличить значение на 1 (124)
