module Main where
import Control.Concurrent.Async
import Control.Concurrent.MVar
import System.Environment
import System.IO
import System.Process
main :: IO ()
main = do
args <- getArgs
(Just i, Just o, Nothing, p) <- createProcess (proc "socat" args)
{std_in = CreatePipe, std_out = CreatePipe}
sequence_ [hSetBuffering h NoBuffering | h <- [i, o, stdin, stdout]]
hSetEcho stdin False
mine <- newEmptyMVar
res <- concurrently
(do c <- getChar
putMVar mine c
hPutChar i c)
(do other <- hGetChar o
mine' <- takeMVar mine
return (mine', other))
print $ snd res
terminateProcess p
I在不同的终端中启动了两个实例,例如:
$ cabal run myprogram -- TCP-LISTEN:12345,fork - # in terminal 1
$ cabal run myprogram -- TCP-CONNECT:localhost:12345 - # in terminal 2
(按照该顺序)然后我在每个终端中击中一个键(无关紧要),它们都将在一对中打印这两个键(侧面交换)。
有时,尽管我首先击中了终端1中的钥匙,那么终端中的过程不会返回(而终端2中的一个则不返回)。
并非并非特别的编程经验,我不会因为僵局而感到惊讶,但是我看不出这是怎么回事!这是我的观察/推理:末端2总是返回(至少我从未见过它没有返回); 如果我在
putStrLn "hello"
;
如果我交换行print $ snd res
print $ snd res
terminateProcess p
而另一个线程在该程序运行中的同一单个snd res
1
中的A型charterminal
1中的App
将这些数据发送到Socat
2SOCAT
2然后您在端子中输入字符2
2 App2
中的所有线程都完成了,它都打印出炭,并且终止socat2至关重要的是,它有机会将任何数据发送给socat1
app1
永远等待Socat发送char