标签: stm

一个处理管道,2个相同类型的IO源

在我的GHC Haskell应用程序中使用stm,network-conduit和conduit,我为每个socket自动分叉使用了一个strand runTCPServer.Strands可以通过使用广播TChan与其他线路进行通信.

这展示了我想如何建立管道"链":

在此输入图像描述

所以,我们这里有两个源(每个都绑定到辅助管道),它们产生一个接受并转入的Packet对象,然后发出套接字.对于两个输入的有效(性能是一个问题),我遇到了很大的困难.encoderByteString

如果有人能指出我正确的方向,我将不胜感激.


既然我没有尝试就发布这个问题是不礼貌的,我会把我以前在这里尝试过的东西放进去;

我已经编写/编写了一个函数,它(阻塞)从TMChan(可关闭的通道)生成一个源;

-- | Takes a generic type of STM chan and, given read and close functionality,
--   returns a conduit 'Source' which consumes the elements of the channel.
chanSource 
    :: (MonadIO m, MonadSTM m)
    => a                    -- ^ The channel
    -> (a -> STM (Maybe b)) -- ^ The read function
    -> (a -> STM ())        -- ^ The close/finalizer function
    -> Source m b
chanSource …
Run Code Online (Sandbox Code Playgroud)

networking haskell tms stm conduit

62
推荐指数
1
解决办法
2292
查看次数

使用软件事务内存的任何真实体验?

似乎最近对STM(软件事务内存)框架和语言扩展的兴趣日益增加. 特别是Clojure有一个很好的实现,它使用MVCC(多版本并发控制)而不是滚动提交日志.GHC Haskell也有一个非常优雅的STM monad,它也允许交易组成.最后,为了给自己的号角做一点点,我最近为Scala实现了一个静态强制引用限制的STM框架.

所有这些都是有趣的实验,但它们似乎仅限于那个领域(实验).所以我的问题是:你们有没有在现实世界中看到过或使用过STM?如果是这样,为什么?它带来了什么样的好处?性能怎么样?(关于这一点似乎存在大量相互矛盾的信息)你会再次使用STM还是更喜欢使用像actor这样的其他并发抽象?

language-agnostic haskell scala clojure stm

60
推荐指数
4
解决办法
5021
查看次数

TVar和TMVar之间的区别

我已经看到它TVar是一个简单的容器,而它TMVar是一个MVar,意思是它有一个锁等,但在STMmonad中.我想知道为什么这是必要的,因为想法STM是不需要锁.

那么,如果你有一个类似于[Handle]你想要在线程之间使用的套接字句柄列表的类型,那么哪个是使用的forkIO

concurrency haskell stm

43
推荐指数
2
解决办法
5697
查看次数

并发通用数据结构,没有死锁或资源不足

我最近问了很多关于的问题TVar,我仍然对活锁感到担忧.

所以我想到了这个结构:

  1. 每个事务都获得唯一的优先级(可能按创建顺序分配).
  2. 事务尝试对它们访问的数据进行读/写锁定.当然,同时读取是可以的,但是一个写入锁定排除了所有其他(读取和写入).
  3. 假设事务A具有比事务B更高的优先级.如果A持有锁,则B等待,但如果B持有锁并且A想要它,则B从锁启动,A获得它,并且事务B重新启动(如同TVar).然而,B保持其当前重试的优先级.
  4. 当释放锁并且有等待事务时,它将进入优先级最高的事务,其余事务继续等待.

我相信这个系统可以防止死锁,但也可以防止饥饿(不像TVar).我想知道是否有人实施了这样的系统,因为它看起来相当明显,我不想重新发明轮子.

当然,可以容易地扩展这种方法以允许用户指定优先级.

优先级可能是一对(user_supplied_prio, auto_increment),与user_supplied_prio采取优先次序,但相同优先级的任务以FIFO的顺序解决.

评论/解决方案:

实际上,当我想到它时,我所描述的已经存在于Haskell中,只需使用一个IORef包裹所有数据,并且仅使用atomicModifyIORef.这atomicModifyIORef将确保按顺序应用交易.但是,有人可能认为这意味着数据结构是顺序的(即有效地限于一个线程),但由于懒惰,它实际上是并行的.

要解释这一点,请考虑一个昂贵的功能f.我们将Data.Map使用键"foo" 将其应用于数据.

这取代(foo -> x)(foo -> future(f x)).这个帖子应该继续解决(f x)实际问题,但在此期间我们可以将g应用于"bar".由于将g应用于"bar"不需要"foo"的结果,我们可以同时解决这个问题.

没有死锁,没有饥饿,最终将处理所有交易(大致按照收到的顺序).

concurrency haskell deadlock stm

39
推荐指数
1
解决办法
1144
查看次数

何时/为什么在TVar上使用MVar

我觉得TVar很容易使用,即使MVar看起来更简单一些,而TVar更有特色.

所以我的问题很简单,我想要什么条件去MVar而不是TVar?我想任何时候我都不需要事务更新我可以使用一个MVar,但这对我有什么好处?

haskell shared-memory stm

36
推荐指数
2
解决办法
5413
查看次数

Clojure STM与Haskell STM有何不同?

我试图找到Clojure所谓的STM和Haskell中实现的STM之间的差异.除了实际的语言语义差异外,我有点困惑,因为Rich Hickey在演讲中说Clojure的STM实现与其他任何东西都有很大不同,但我不理解除语言选择之外的差异.

haskell language-comparisons transactional-memory clojure stm

32
推荐指数
3
解决办法
3271
查看次数

Haskell快速并发队列

问题

你好!我正在编写一个日志库,我很乐意创建一个在单独的线程中运行的记录器,而所有应用程序线程都只是向它发送消息.我想为这个问题找到性能最佳的解决方案.我在这里需要简单的unboud队列.

途径

我已经创建了一些测试来查看可用解决方案的执行情况,我在这里得到了非常奇怪的结果.我测试了4个实现(下面提供的源代码)基于:

  1. 管道并发
  2. Control.Concurrent.Chan
  3. Control.Concurrent.Chan.Unagi
  4. 基于"Haskell中的并行和并发编程"一书中描述的MVar请注意,这种技术为我们提供了容量为1的有限队列 - 它仅用于测试

测试

以下是用于测试的源代码:

{-# LANGUAGE NoMonomorphismRestriction #-}

import Control.Concurrent (threadDelay)
import Control.Monad (forever)
import Pipes
import qualified Pipes.Concurrent as Pipes
import Control.Applicative
import Control.Monad (replicateM_)
import System.Environment (getArgs)

import Control.Concurrent.Chan
import Control.Concurrent (forkIO)
import qualified Control.Concurrent.Chan.Unagi as U
import Control.Concurrent.MVar
import Criterion.Main

data Event = Msg String | Status | Quit deriving (Show)

----------------------------------------------------------------------
-- Pipes
----------------------------------------------------------------------

pipesLogMsg = yield (Msg "hello")
pipesManyLogs num = replicateM_ num pipesLogMsg

pipesAddProducer num …
Run Code Online (Sandbox Code Playgroud)

concurrency profiling haskell stm haskell-pipes

25
推荐指数
2
解决办法
2207
查看次数

你如何实现软件事务内存?

就实际的低级原子指令和内存栅栏而言(我假设它们已被使用),您如何实现STM?

对我来说神秘的部分是,给定一些任意代码块,您需要一种方法可以在之后返回并确定每个步骤中使用的值是否有效.你是怎么做到的,你如何有效地做到这一点?这也似乎表明,就像任何其他"锁定"解决方案一样,您希望保持关键部分尽可能小(以减少冲突的可能性),我是对的吗?

此外,STM可以简单地检测"在执行计算时进入该区域的另一个线程,因此计算无效"或者它是否可以实际检测是否使用了破坏的值(因此运气时有时两个线程可以同时执行相同的临界区需要回滚)?

multithreading atomic stm

22
推荐指数
3
解决办法
3717
查看次数

STM性能不佳/锁定

我正在编写一个程序,其中有大量代理监听事件并对它们做出反应.由于Control.Concurrent.Chan.dupChan被弃用,我决定使用TChan的广告.

TChan的表现比我预期的要糟糕得多.我有以下程序来说明问题:

{-# LANGUAGE BangPatterns #-}

module Main where

import Control.Concurrent.STM
import Control.Concurrent
import System.Random(randomRIO)
import Control.Monad(forever, when)

allCoords :: [(Int,Int)]
allCoords = [(x,y) | x <- [0..99], y <- [0..99]]

randomCoords :: IO (Int,Int)
randomCoords = do
  x <- randomRIO (0,99)
  y <- randomRIO (0,99)
  return (x,y)

main = do
  chan <- newTChanIO :: IO (TChan ((Int,Int),Int))

  let watcher p = do
         chan' <- atomically $ dupTChan chan
         forkIO $ forever $ do
                    r@(p',_counter) <- atomically $ …
Run Code Online (Sandbox Code Playgroud)

concurrency performance haskell stm

20
推荐指数
3
解决办法
3263
查看次数

我应该如何使一个clojure STM程序持久化?

我正在编写一个使用STM的clojure程序.目前,我在数据库启动时填充STM(使用refs),然后在dosync事务成功时异步更新数据库.我不知道我是否以正确的方式这样做,或者是否有更好的标准技术来做到这一点.谁能向我解释他们如何在他们的Clojure程序中将STM的ACI属性变成ACID?

clojure stm

17
推荐指数
1
解决办法
3002
查看次数