Я пытаюсь использовать каналы/STM для реализации передачи сообщений в Haskell. Возможно, это ужасная идея, и есть лучший способ реализовать/использовать передачу сообщений в Haskell. Если это так, дайте мне знать; Тем не менее, мои поиски открыли некоторые основные вопросы о параллельном Haskell.Haskell, Channels, STM, -threaded, Message Passing
Я слышал о вещах STM, в частности о реализации в Haskell. Поскольку он поддерживает чтение и запись, и имеет некоторые преимущества в плане безопасности, я решил, что он начнется там. Это вызывает мой самый большой вопрос: действительно
msg <- atomically $ readTChan chan
где чан является TChan Int, вызывает ожидание, что ждет канала, чтобы иметь значение на нем?
Рассмотрим следующую программу:
p chan = do
atomically $ writeTChan chan 1
atomically $ writeTChan chan 2
q chan = do
msg1 <- atomically $ readTChan chan
msg2 <- atomically $ readTChan chan
-- for testing purposes
putStrLn $ show msg1
putStrLn $ show msg2
main = do
chan <- atomically $ newTChan
p chan
q chan
Compile это с GHC --make -threaded, а затем запустить программу, и на самом деле вы получаете 1, затем 2 напечатаны на консоли. Предположим, что мы делаем
main = do
chan <- atomically $ newTChan
forkIO $ p chan
forkIO $ q chan
вместо этого. Теперь, если мы будем использовать - threaded, он либо ничего не напечатает, 1 или 1, а 2 - к терминалу; однако, если вы не компилируете с помощью -threaded, он всегда печатает 1, а затем 2. Вопрос 2: в чем разница между -тобой и нет? Я предполагаю, что они на самом деле не работают как параллельные вещи, и они просто запускаются один за другим. Это соответствует следующему.
Теперь, когда я думал, что у меня были p и q, работающие одновременно; т. е. я их сделал, они должны иметь возможность работать в обратном порядке. Предположим, что
main = do
chan <- atomically newTChan
forkIO $ q chan
forkIO $ p chan
Теперь, если я скомпилирую это без искажений, я никогда не получаю ничего напечатанного на консоли. Если я скомпилирую с помощью -threaded, я иногда это делаю. Хотя, очень редко можно получить 1, а затем 2 - обычно 1 или ничего. Я попробовал это и с Control.Concurrent.Chan, и получил согласованные результаты.
Второй большой вопрос: как каналы и вилка играют вместе, и что происходит в вышеуказанной программе?
Во всяком случае, кажется, что я не могу так наивно моделировать передачу сообщений с помощью STM. Возможно, Cloud Haskell - это вариант, который решает эти проблемы - я действительно не знаю. Любая информация о том, как получить передачу сообщения, нежели сериализовать ~~> записать в сокет ~~>, читается из сокета ~~> десериализации, была бы чрезвычайно оценена.
Re: «какая разница между -threaded и не», вы могли бы [ моя экспозиция на поточной модели Haskell] (http://dmwit.com/gtk2hs). Игнорировать специфичные для gtk биты. –