Haskell STM и повторите попытку

Когда мы запускаем выражение STM, которое достигает retry, поток блокируется, и транзакция запускается еще раз, если записи изменены.

Но мне было интересно:

  • Если мы прочитаем переменную STM, которая в этой конкретной ветке, ведущей к повторной попытке, на самом деле не используется, будет ли ее обновление пытаться выполнить транзакцию снова?

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


person nicolas    schedule 31.03.2016    source источник
comment
Я изо всех сил пытаюсь следовать вашему первому вопросу. Как насчет привести пример? Что касается вашего второго вопроса: ветка заблокирована. Однако потоки Haskell по умолчанию являются зелеными потоками, поэтому многие из них выполняются в одном системном потоке. Это означает, что другие потоки Haskell по-прежнему смогут работать, пока он заблокирован.   -  person Will Sewell    schedule 31.03.2016
comment
Для 1-го вопроса: если прочитать 2 переменные, но моя транзакция на самом деле зависит от значения только 1   -  person nicolas    schedule 31.03.2016
comment
Ясно. Я думаю, что зеленый поток достаточно эффективен, чтобы не заботиться о реализации в первом приближении.   -  person nicolas    schedule 31.03.2016
comment
Для 1) я бы сказал да, если вы прочитаете его и повторите попытку, любые изменения в нем приведут к повторной попытке перехода. Если вы не используете его, вы не должны его читать. Или, другими словами, больше показаний, близких к точкам использования.   -  person chi    schedule 31.03.2016


Ответы (2)


  1. Да. Чтение переменной STM вызовет stmReadTVar — см. здесь. Это создаст новую запись в записи транзакции, и она будет проверена при фиксации. Если вы посмотрите здесь, вы найдете что ReadTVarOp помечен как операция с побочным эффектом (has_side_effects = True), поэтому я не думаю, что компилятор устранит его независимо от того, будете ли вы использовать его результат или нет.
  2. Как писал @WillSewell, Haskell использует зеленые потоки. Вы даже можете использовать STM в однопоточной среде выполнения, не беспокоясь о том, что фактический поток ОС будет заблокирован.
person schernichkin    schedule 31.03.2016

Ре. 1: насколько я понимаю ваш вопрос, да, это правильно; вся ваша транзакция STM будет иметь согласованное представление мира, включая ветви, составленные с помощью orElse (см.: https://ghc.haskell.org/trac/ghc/ticket/8680). Но я не уверен, что вы подразумеваете под «но моя транзакция на самом деле зависит от значения только 1 переменной»; если вы сделаете readTVar, то изменения в этой переменной будут отслеживаться.

Ре. 2: вы можете думать о зеленых потоках как о кусках сохраненного состояния вычислений, которые хранятся в стекоподобной вещи и извлекаются, работают некоторое время и возвращаются в стек, когда они не могут двигаться дальше в настоящее время. («заблокирован») или после того, как они проработали достаточно долго. Степень, в которой это происходит параллельно, зависит от количества потоков ОС, которые вы указываете среде выполнения (через +RTS -N). У вас может быть параллельная программа, которая использует тысячи зеленых потоков, но работает только с одним потоком ОС, и это совершенно нормально.

person jberryman    schedule 31.03.2016