Объясните это состояние гонки в Ruby - PullRequest
0 голосов
/ 17 февраля 2019

Четыре цикла по 10 миллионов раз каждый.В каждом цикле они нажимают число, если список пуст, иначе они извлекают число из списка.

list = []

threads = []

4.times do |i|
  threads << Thread.new do
    1e7.to_i.times do |i|
      if list.empty?
        list << i
      else
        list.pop
      end
    end
  end
end

threads.each(&:join)
p list

Поскольку цикл выполняется четное число раз, я ожидаю, что список будет пустым после всехпотоки выполняются.

Однако иногда список содержит номер 9999999.

Я думал, что массив в MRI Ruby является потокобезопасным из-за GIL.

КакРасовые условия бывают несмотря на GIL?

1 Ответ

0 голосов
/ 17 февраля 2019

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

В вашем примереВозможно, что один поток читает и оценивает list.empty?, а затем должен ждать другого потока.Другой поток также читает и оценивает list.empty? и получает тот же результат, что и первый поток.После этого оба потока выполнят одну и ту же ветку условия if, поскольку они видели одно и то же состояние.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...