几个分叉进程中的第二个不在Haskell中运行(GHC 7.8.4)

时间:2015-12-05 03:46:13

标签: perl haskell io

我有一个简单的Haskell程序,可以分解几个进程,每个进程都会休眠一定时间,然后回声。无论我分叉了多少个进程,第二个进程似乎都没有向终端输出任何可见内容。

./scheduler 
user@name-of-computer $ 1
3
4
5

产生

$ 1.haskell  4.haskell
3.haskell  5.haskell

如果您使用注释行而不是仅仅打印来运行它,您可以看到

use strict;
use warnings FATAL => 'all';

sub sleep_echo {
  my ($second_count) = @_;
  my $cpid = fork;
  if ($cpid == 0) {
    exec "sleep $second_count; echo $second_count";
  }
}

for (my $i = 1; $i <= 5; $i++) {
  sleep_echo($i);
}

这种行为似乎也特定于Haskell。 Perl没有展出它。

user@name-of-computer $ 1
2
3
4
5

打印

NULL

关于发生了什么的任何想法?

1 个答案:

答案 0 :(得分:3)

我已经能够用GHC 7.10.2重现这一点。

Haskell和Perl版本并不完全等效。 Perl版本将创建一个进程后的进程,等待前一个进程启动(未完成)。

Haskell版本将创建多个线程,每个线程启动一个进程。

由于您不等待线程完成启动它们的进程,因此某些线程将因为程序结束太快而失败。 Haskell运行时中的线程执行不是随机的,因此您的程序将(通常)在您的机器上反复出现相同的行为。

您还可以尝试增加进程数以查看发生的情况。有14个进程,第13个进程未启动(在我的配置中)。

如果您删除forkIO来电,您的程序就可以正常运行:

import System.Process (createProcess, proc, shell, CreateProcess)
import Text.Printf (printf, PrintfArg)
import Control.Monad (void)

sleep :: Integer -> CreateProcess
sleep x = shell (printf "sleep %d; echo %d" x x)

main = foldr1 (>>)
              [ void $ createProcess task
              | task <- fmap sleep [1..5]
              ]