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

我是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
    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

但是,当我运行程序时,它会立即结束而不做任何事情?我怎样才能做到这一点呢?

这里有两件事:

  • HTTP库只支持不安全的HTTP,不支持HTTPS。解释你能做些什么。无论如何,如果您尝试使用HTTPS,它会在IO中引发异常
  • forkFinally
    接受自身内部抛出的任何异常,并在
    左侧返回它们。但是,接受
    的代码只是
    (\\\->writeChan waitq())
    ,因此您将丢弃异常并继续执行,就好像它成功了一样。这就解释了为什么你看不出哪里出了问题

  • 它对我有用。你给它的输入文件里有什么?是否所有的URL都在最后一个
    /
    之后有一个文件名?另外,您是否真的对并发有实际的用途,或者您只是想学习如何使用它?如果是前者,您是否考虑过只同时使用
    Map.
    ?@JosephSible我有69个URL,它们都以
    https://
    开头,并且有一个路径组件。我试图用这个来控制并发文件下载的最大数量。我不知道
    mapu>是如何工作的。如果直接从GHCi调用
    retrieveUrls
    会发生什么?仅检索<代码>如何?请参阅设置限制。