Haskell 并发下载立即结束
我是Haskell的新手,写了以下程序作为练习Haskell 并发下载立即结束,haskell,Haskell,我是Haskell的新手,写了以下程序作为练习 Main.hs module Main (main) where import ParallelDownloader import System.IO (hPutStrLn,stderr) import GHC.IO.Encoding (setLocaleEncoding, utf8) import System.Environment (getArgs) main :: IO () main = do setLocaleEncod
Main.hs
module Main (main) where
import ParallelDownloader
import System.IO (hPutStrLn,stderr)
import GHC.IO.Encoding (setLocaleEncoding, utf8)
import System.Environment (getArgs)
main :: IO ()
main = do
setLocaleEncoding utf8
args <- getArgs
case args of
[inputFile] -> do
fileContents <- readFile inputFile
retrieveUrls 4 (lines fileContents)
_ -> hPutStrLn stderr "Input File Not Specified"
module ParallelDownloader where
import System.IO
import Network.HTTP
import Control.Concurrent
import Control.Monad(forM_)
fetchUrl url = simpleHTTP (getRequest url) >>= getResponseBody
retrieve url savePath = do
responseData <- fetchUrl url
writeFile savePath responseData
getPath :: String -> String
getPath = reverse . takeWhile (/= '/') . reverse
workerThread q = do
url <- readChan q
if url == "" then
return ()
else do
retrieve url (getPath url)
workerThread q
retrieveUrls :: Int -> [String] -> IO ()
retrieveUrls numThread urls = do
que <- newChan
waitq <- newChan
forM_ urls $ \u -> writeChan que u
forM_ [1..numThread] $ \_ -> writeChan que ""
forM_ [1..numThread] $ \_ -> forkFinally (workerThread que) (\_ -> writeChan waitq ())
forM_ [1..numThread] $ \_ -> readChan waitq
但是,当我运行程序时,它会立即结束而不做任何事情?我怎样才能做到这一点呢?这里有两件事:
forkFinally
接受自身内部抛出的任何异常,并在的左侧返回它们。但是,接受或的代码只是(\\\->writeChan waitq())
,因此您将丢弃异常并继续执行,就好像它成功了一样。这就解释了为什么你看不出哪里出了问题
它对我有用。你给它的输入文件里有什么?是否所有的URL都在最后一个
/
之后有一个文件名?另外,您是否真的对并发有实际的用途,或者您只是想学习如何使用它?如果是前者,您是否考虑过只同时使用Map.
?@JosephSible我有69个URL,它们都以https://
开头,并且有一个路径组件。我试图用这个来控制并发文件下载的最大数量。我不知道mapu>是如何工作的。如果直接从GHCi调用retrieveUrls
会发生什么?仅检索<代码>如何?请参阅设置限制。