Существуют ли расы в путе? - PullRequest
0 голосов
/ 27 марта 2019

Я читаю сообщение о потоках для ruby. И есть фрагмент:

q = Queue.new
producer = Thread.new {
  c = 0
  while true do
    q << c
    c += 1
    puts "#{q.size} in stock"
  end
}
consumer1 = Thread.new {
  while true
    val = q.shift
    puts "Consumer - 1: #{val}"
  end
}
consumer2 = Thread.new {
  while true
    val = q.shift
    puts "Consumer - 2: #{val}"
  end
}

[producer, consumer1, consumer2].each(&:join)

В сообщении говорится, что результат будет такой:

Thread 2: 25
Thread 1: 22
Thread 2: 26Thread 1: 27
Thread 2: 29
Thread 1: 28

и причина:

... довольно распространенное состояние гонки ...

Но я не смог воспроизвести этот вывод. И как программист Java, я не думаю, что результат, связанный с состоянием гонки здесь. Я верю, что это что-то связанное с puts, но я понятия не имею об этом.

Что здесь происходит?


UPDATE

Спасибо за помощь @Damien MATHIEU, которая многое объясняет рубиновому новичку. Я нашел другой ответ в ОС для STDOUT.sync = true, который хорошо объясняет, зачем он нам нужен и какие проблемы это может вызвать.

Назначение:

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

Возможные проблемы, как и ожидалось (и что произошло в моем вопросе):

Такое поведение приводит к проблемам в определенных ситуациях. Представьте, что вы хотите построить индикатор выполнения (запустите цикл, который выводит отдельные точки между обширными вычислениями). С буферизацией может получиться так, что какое-то время не будет никакого вывода, а затем внезапно будут распечатаны сразу несколько точек.

1 Ответ

5 голосов
/ 27 марта 2019

Это потому, что puts не записывает в STDOUT сразу, но буферизует строку и записывает большими кусками.

Вы можете получить ruby ​​для немедленной записи со следующим:

STDOUT.sync = true

, которая должна решить вашу проблему с заказом.

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