Strange behavior with concurrency in Haskell

I have the following code:

import Control.Concurrent sleepSort = mapM_ (forkIO . put) where put x = threadDelay (x*10000) >> print x 

This does a sorting of sleep by a set of integers and works fine except for one caveat:

The program prints each of the numbers in the data set in sequence, as expected. However, after he finishes printing the last number, he waits for the user to dial a certain number, and then repeat the echo number and then complete.

I don't think I'm asking for data entry at any time, so why is this happening?

+6
source share
1 answer

This is because your main thread is not waiting for the rest of the threads to complete. Your program starts n threads, but the main thread exits immediately, and you return back to the prompt of the interpreter. Meanwhile, other threads continue to produce the conclusion:

 Prelude Control.Concurrent> sleepSort [1,2,3] 1 Prelude Control.Concurrent> 2 3 

You can fix this by adding a delay to the main thread:

 Prelude Control.Concurrent> sleepSort [1,2,3] >> threadDelay 10000 1 2 3 

If you run the compiled program, it will immediately exit without printing:

 $ cat Test.hs import Control.Concurrent sleepSort = mapM_ (forkIO . put) where put x = threadDelay (x*1000) >> print x main = sleepSort [1,2,3] $ ghc --make -O2 Test.hs [1 of 1] Compiling Main ( Test.hs, Test.o ) Linking Test ... $ ./Test $ 

Update: Instead of adding a threadDelay call to main you can use the semaphore in the sleepSort function:

 import Control.Concurrent import Control.Concurrent.QSemN sleepSort l = do qsem <- newQSemN 0 mapM_ (forkIO . put qsem) l waitQSemN qsem n where n = length l put qsem x = threadDelay (x*1000) >> print x >> signalQSemN qsem 1 main = sleepSort [1,2,3] 
+7
source

Source: https://habr.com/ru/post/923711/


All Articles