Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 选择性发送到TChan?_Multithreading_Haskell_Stm - Fatal编程技术网

Multithreading 选择性发送到TChan?

Multithreading 选择性发送到TChan?,multithreading,haskell,stm,Multithreading,Haskell,Stm,AFAIK TChan作为一个中心,发送的每一条信息都被其他人看到,对吗 我想要一个TChan,它充当一个开关,向特定线程发送消息,并支持广播。 有这样的事吗?编辑:我重新阅读了你的问题。这个答案并不完全针对“选择性发送”,尽管它澄清了TChan可以做什么 下面描述的“广播”方法将唤醒所有的听众(尽管好的一面是,它不会为每个项目制作1000份拷贝)。为了避免这种情况,请使用@Mikhail建议的Map方法。我是在我的家庭里做的 TChan是一个先进先出队列: writeTChan在末尾添加一

AFAIK TChan作为一个中心,发送的每一条信息都被其他人看到,对吗
我想要一个TChan,它充当一个开关,向特定线程发送消息,并支持广播。

有这样的事吗?编辑:我重新阅读了你的问题。这个答案并不完全针对“选择性发送”,尽管它澄清了
TChan
可以做什么

下面描述的“广播”方法将唤醒所有的听众(尽管好的一面是,它不会为每个项目制作1000份拷贝)。为了避免这种情况,请使用@Mikhail建议的
Map
方法。我是在我的家庭里做的


TChan
是一个先进先出队列:

  • writeTChan
    在末尾添加一项

  • readTChan
    从头开始读取项目

例如,以下示例分叉了10个线程,它们在单个通道上进行斗争:

import Control.Concurrent
import Control.Concurrent.STM
import Control.Monad

main = do
    chan <- newTChanIO

    forM_ [1..10] $ \i ->
        forkIO $
            forever $ do
                x <- atomically $ readTChan chan
                putStrLn $ "Thread " ++ show i ++ ": " ++ show x

    mapM_ (atomically . writeTChan chan) [1..1000]

    -- Wait for channel to empty out
    atomically $ do
        empty <- isEmptyTChan chan
        when (not empty) retry
导入控制。并发
导入控制.Concurrent.STM
进口管制
main=do
陈
福基奥$
永远$do

编辑:我重读了你的问题。这个答案并不完全针对“选择性发送”,尽管它澄清了
TChan
可以做什么

下面描述的“广播”方法将唤醒所有的听众(尽管好的一面是,它不会为每个项目制作1000份拷贝)。为了避免这种情况,请使用@Mikhail建议的
Map
方法。我是在我的家庭里做的


TChan
是一个先进先出队列:

  • writeTChan
    在末尾添加一项

  • readTChan
    从头开始读取项目

例如,以下示例分叉了10个线程,它们在单个通道上进行斗争:

import Control.Concurrent
import Control.Concurrent.STM
import Control.Monad

main = do
    chan <- newTChanIO

    forM_ [1..10] $ \i ->
        forkIO $
            forever $ do
                x <- atomically $ readTChan chan
                putStrLn $ "Thread " ++ show i ++ ": " ++ show x

    mapM_ (atomically . writeTChan chan) [1..1000]

    -- Wait for channel to empty out
    atomically $ do
        empty <- isEmptyTChan chan
        when (not empty) retry
导入控制。并发
导入控制.Concurrent.STM
进口管制
main=do
陈
福基奥$
永远$do

你不能用一个广播TChan并丢弃发送给其他线程的消息吗?我想了想,但是唤醒1000个线程,只有一个线程接收到它,这听起来效率很低。我想你应该使用
映射ThreadId TChan
并进行自己的广播。haskell中有线程安全的映射吗?因为haskell数据是不可变的,大多数数据结构已经是线程安全的了。要修改来自多个线程的可变数据,将其放在
TVar
中可能是最简单的方法。难道不能使用广播TChan并丢弃发送给其他线程的消息吗?我考虑过,但是唤醒1000个线程,只有一个线程接收到它,这听起来效率很低。我想你应该使用
映射ThreadId TChan
并进行自己的广播。haskell中有线程安全的映射吗?因为haskell数据是不可变的,大多数数据结构已经是线程安全的了。要修改来自多个线程的可变数据,将其放入
TVar
可能是最简单的方法。您的方法类似于erlang消息传递样式,每个客户端都有一个专用TChan和一个broadcating映射(erlang中的ets表)。对于聊天服务器应用程序,您认为erlang比haskell好吗?@user1748906:我没有做过任何erlang,但我认为它有一个非常好的并发模型。如果您计划编写一个主要是通信和并发的程序,我建议您首先在Erlang中尝试。即使您决定稍后将程序移植到Haskell,您也会将从Erlang学到的思想随身携带。您的方法看起来像Erlang消息传递风格,每个客户端都有一个专用TChan和一个broadcating映射(Erlang中的ets表)。对于聊天服务器应用程序,您认为erlang比haskell好吗?@user1748906:我没有做过任何erlang,但我认为它有一个非常好的并发模型。如果您计划编写一个主要是通信和并发的程序,我建议您首先在Erlang中尝试。即使您决定稍后将程序移植到Haskell,您也会随身携带从Erlang学到的思想。