2016-07-11 3 views
0

Программа:Взаимное исключение не произошло в Рубине

def inc(n) 
    n + 1 
end 

sum = 0 
threads = (1..10).map do 
    Thread.new do 
     10_000.times do 
      sum = inc(sum) 
     end 
    end 
end 
threads.each(&:join) 
p sum 

Выход:

$ ruby MutualExclusion.rb 
100000 
$ 

Мой ожидается выход выше программы составляет менее 100000. Потому что вышеуказанная программа создает 10 потоков, и каждый из потока обновляет общую сумму «sum» до 10000 раз. Но во время выполнения программы обязательно произойдет взаимное исключение. Потому что здесь не обрабатывается взаимное исключение, . Поэтому я ожидаю, что менее 100 000 в качестве выпуска. Но он дает ровно 100 000 в качестве выхода. Как произошло ? Кто занимается взаимным исключением здесь? И как я экспериментирую с этой проблемой (ME).

+0

ли вы проверить код на МРТ или JRuby? – spickermann

+0

@spickermann Нет. Я новичок. И я не знал об этом. – mrg

+0

@spickermann, который сказал, MRI :) – mudasobwa

ответ

0

Интерпретатор по умолчанию для Ruby (MRI) не выполняет потоки параллельно. Механизм, предотвращающий непредсказуемое поведение вашей гонки, - это Global Interpreter Lock (GIL).

Вы можете узнать больше об этом, в том числе очень похожем демонстрации, здесь: http://www.jstorimer.com/blogs/workingwithcode/8085491-nobody-understands-the-gil

+0

Просто я получил недоумение. Вы считаете, что это правильно. Потому что вместо правильной обработки взаимного исключения, вполне нормально устанавливать свойство как «только один поток может выполнять Ruby-код в любой момент». В связи с этим избегается параллельное выполнение потока. Это разрушает основное использование потока. Что Вы думаете об этом. Это за или против рубин? – mrg

+0

@mrg Не обязательно; это зависит от того, что вы делаете. Особенно при создании веб-сервисов вы будете делать много ввода-вывода (например, запросы API); планировщик потоков может приостанавливаться, тогда как IO выполняет в фоновом режиме, обрабатывая другие запросы тем временем. Однако для задач, связанных с процессором, рекомендуется использовать другой интерпретатор (rbx/rubinius неплохо). – coreyward

+0

Так что я беру МРТ, хорошо для веб-сервисов, а rbx хорош для задачи, связанной с процессором? – mrg

Смежные вопросы