LINUX.ORG.RU

ConditionVariable.wait: 1.8 vs 1.9

 condition variable, ,


0

0

обьясните мне почему код метода wait так отличается между версиями

1.8

def wait(mutex)
  begin
    mutex.exclusive_unlock do
      @waiters.push(Thread.current)
      Thread.stop
    end
  ensure
    mutex.lock
  end
end

1.9

def wait(mutex, timeout=nil)
  begin
    # TODO: mutex should not be used
    @waiters_mutex.synchronize do
      @waiters.push(Thread.current)
    end
    mutex.sleep timeout
  ensure
    @waiters_mutex.synchronize do
      @waiters.delete(Thread.current)
    end
  end
  self
end

как по мне то автор кода для ветки 1.9 явно что-то курил

все что удалось нагуглить — это ссылка в багзилле

★★★★★

disclaimer: я не рубист, исходников RMI не читал.

Судя по всему, верное и правильное изменение, так как учитывает семантику condvar'ов. Ведь spurious wakeup'ы возможны всегда.

dmitry_vk ★★★
()
Ответ на: комментарий от dmitry_vk

ну хорошо. с spurious wakeup'ами нужно что-то делать. но не нужно ламать базовой функционал. но давайте по порядку.

для меня код в 1.8 работает предельно ясно(ну почти)

  • exclusive_unlock — единственное что не понятно
  • push - добавили поточный тред во внутренний массив
  • stop - сделали ему стоп. логично после wait тред должен ждать
  • ensure mutex.lock - так как мы делали анлок - то надо «все вернуть на место»

а что мы имеем в 1.9

  • waiters_mutex.synchronize - согласен. добавление нужно делать «под колпаком»
  • push - тоже самое
  • sleep - ну спим. по надобности.
  • waiters_mutex.synchronize .. .delete - «под колпаком» удаляем

а теперь вопросы для по 1.9:

  • почему в 1й части нету stop? оно что само как то делается?
  • если забыть о spurious wakeup то что же получается (для случая с 1 тредом): добавили и тут же удалили? а когда придет signal то он никого не розбудит? // атлична

На so есть тред с реализацией thread pool на руби. Он чудесно работает в 1.8 а в 1.9 - фигушки (даже с 1 воркером). и как раз по той причине что я описал

Да есть замечательный gem work_queue но мне вообще непонятно как он работает, да и хотелось бы разобратся что здесь не так

ZuBB ★★★★★
() автор топика
Ответ на: комментарий от ZuBB

почему в 1й части нету stop? оно что само как то делается?

Видимо, mutex.sleep это делает. http://www.ruby-doc.org/core-1.9.3/Mutex.html#method-i-sleep Кстати, в версии от 1.8 нет таймаута.

если забыть о spurious wakeup то что же получается (для случая с 1 тредом): добавили и тут же удалили? а когда придет signal то он никого не розбудит? // атлична

В это время нить спит на mutex.sleep (с разблокированным мьютексом). Видимо, как-то ее достают из @waiters и будят.

На so есть тред с реализацией thread pool на руби. Он чудесно работает в 1.8 а в 1.9 - фигушки (даже с 1 воркером). и как раз по той причине что я описал

В ветке на SO все разобрали и привели пример корректного кода.

dmitry_vk ★★★
()
Ответ на: комментарий от dmitry_vk

В ветке на SO все разобрали и привели пример корректного кода.

да но для 1.8. а для 1.9

This is not happy under MRI 1.9: «thread.rb:185:in `sleep': deadlock detected (fatal)» :( – Martin Carpenter Jun 21 '11 at 13:50

ZuBB ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.