Haskell中没有运行第二个分叉进程(GHC 7.8.4) [英] Second of several forked processes does not run in Haskell (GHC 7.8.4)

查看:128
本文介绍了Haskell中没有运行第二个分叉进程(GHC 7.8.4)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的Haskell程序,它分离出几个进程,每个进程都会休眠几秒钟然后回声。无论我分叉多少个进程,第二个似乎都不会向终端输出任何可见的内容。

  import System。进程(createProcess,proc,shell,CreateProcess)
导入Text.Printf(printf,PrintfArg)
导入Control.Concurrent(forkIO)
导入Control.Monad(void)

sleep :: Integer - > CreateProcess
sleep x = shell(printfsleep%d; echo%dxx)
- sleep x = shell(printfsleep%d,echo%d,touch%d.haskellxxx )

main = foldr1(>>)$ [
forkIO $ void $ createProcess task |
任务< - [睡眠1,睡眠2,睡眠3,睡眠4,睡眠5]]

生成

  ./ scheduler 
用户@计算机名称$ 1
3
4
5

如果您使用注释行而不是只是印刷,你可以看到

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

这种行为似乎也特定于Haskell。 Perl不会显示它。

  use strict; 
使用警告FATAL => '所有';

sub sleep_echo {
my($ second_count)= @_;
my $ cpid = fork;
if($ cpid == 0){
execsleep $ second_count; echo $ second_count; ($ my $ i = 1; $ i <= 5; $ i ++){
sleep_echo($ i);

}

;

$ / code>

打印

  user @电脑名称$ 1 
2
3
4
5

任何关于发生什么的想法? 我已经能够用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(printfsleep%d; echo%dxx)
$ b $ main = foldr1(>>)
[void $ createProcess task
|任务< - fmap sleep [1..5]
]


I have a simple Haskell program that forks off several processes, each of which sleeps for a certain number of seconds and then echos. Regardless of how many processes I fork, the second one does not seem to output any visible content to the terminal.

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

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

main = foldr1 (>>) $ [
  forkIO $ void $ createProcess task |
  task <- [ sleep 1, sleep 2, sleep 3, sleep 4, sleep 5] ]

produces

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

And if you run it with the commented line instead of just printing, you can see

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

This behavior also seems to be specific to Haskell. Perl does not exhibit it.

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);
}

prints

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

Any ideas as to what's going on?

解决方案

I have been able to reproduce this with GHC 7.10.2.

The Haskell and Perl versions are not strictly equivalent. The Perl version will create process after process, waiting the previous one to be launched (not finished).

The Haskell version will create several threads, each one launching one process.

Since you do not wait for your threads to finish launching their process, some threads will fail because your program ends too quickly. Thread execution in the Haskell runtime is not random, therefore your program will (generally) exhibit the same behavior again and again on your machine.

You can also try to increase the number of processes to see what happens. With 14 processes, the 13th process is not launched (on my configuration).

If you remove the forkIO call, your program will work just fine:

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]
              ]

这篇关于Haskell中没有运行第二个分叉进程(GHC 7.8.4)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆