時間のかかる処理をbackgroundで処理して、ブラウザ上は終了させたいのですが、うまく子プロセスが動いてくれません。Windowsだからでしょうか?
Windows 7
IIS 7.5
StrawberryPerl 5.18.4
test.cgi
use strict;
use warnings;
use utf8;
print "Content-Type: text/html; charset=Shift_JIS\n\n";
print "システムコマンド実行\n";
my $pid = fork;
forkが失敗した場合はエラー処理を行う
unless (defined $pid) {
die "fork faild.";
}
close STDIN;
close STDOUT;
close STDERR;
子プロセスは以下を実行
if ($pid == 0) {
system( "perl C:/inetpub/wwwroot/data/script/test_001.pl" );
}
exit(0);
------------ test_001.pl
use strict;
use warnings;
use utf8;
$| = 1;
open TST, "> ./testtest.log";
foreach (1..30) {
print TST $_ . "\n";
sleep(1);
}
close TST;
exit;
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答5件
0
下記のコードで、perl.exe が、2つ起動したのをタスクマネージャーで確認し、コマンドプロンプトでは期待通りの動き(表示は即終了し、2つ目のプロセスが他の処理)をしたのですが、ブラウザを介するとなぜか全てのプロセスの終了が完了するまで、ブラウザで表示してくれませんでした。Perlは悪くないのかもしれず、もしかしたらIISの設定が何か必要なのかもしれません。
use Thread;
$| = 1;
my $thread1 = Thread->new(&thre1, "1");
my $thread2 = Thread->new(&thre2, "2");
$thread1->join;
$thread2->detach;
if ($thread2->is_running()) {
sleep(1);
}
my $result = $thread2->is_detached();
print "result:$result";
sub thre1() {
my ($name) = @;
print "Content-Type: text/html; charset=Shift_JIS\n\n";
print "testtest<br><br>\n\n";
for (1..50) {
print "$name ($)<br>\n";
}
threads->yield();
}
sub thre2() {
my @arg = qw( perl C:/inetpub/wwwroot/data/script/test.pl ); my @res = system ("start", "/B", @arg ); threads->yield();
}
投稿2015/03/03 01:59
総合スコア8
0
以下のコードを実行したところ、コマンドプロンプト上では期待通りの動き(出力即終了&その後もファイル作成)ができましたが、ブラウザ上では無理でした。おそらくIISの設定的な問題かもしれません。ありがとうございました。
use Thread;
$| = 1;
my $thread1 = Thread->new(&thre1, "1");
my $thread2 = Thread->new(&thre2);
$thread1->join;
$thread2->detach;
my $result = $thread2->is_detached();
if ($thread2->is_running()) {
sleep(1);
}
sub thre1() {
my ($name) = @;
print "Content-Type: text/html; charset=Shift_JIS\n\n";
print "testtest<br><br>\n\n";
for (1..50) {
print "$name ($)<br>\n";
}
yield();
}
sub thre2() {
my @arg = qw( perl C:/inetpub/wwwroot/data/script/test_001.pl );
my @res = system ("start", "/B", @arg );
yield();
}
投稿2015/03/02 05:14
総合スコア8
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ご質問の内容と少しずれますが、
UNIX系OSでいうcron、Windowsならタスクスケジューラが利用できるのであれば、以下のような方法もあります。
- データファイルに実行内容(タスク)を記録
- cronでデータファイルを読み込んで実行内容にそって実行
例えば
・Aさんがアクセス→データファイルには1を記録
・Bさんがアクセス→データファイルには2を記録
・cronでデータファイルを読み込んで2回実行する
といった感じです。
(実際にデータファイルには1行ずつ追記していく形が多いですかね)
この方法の利点は、大量にリクエストがあった場合でも重たい(時間のかかる)処理が一度に大量に走らない点です。ご参考まで。
投稿2015/02/26 03:39
総合スコア783
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
コメントにしようとして失敗しました。すいません。
時間のかかる処理をbackgroundで処理して、ブラウザ上は終了させたいのですが、うまく子プロセスが動いてくれません。Windowsだからでしょうか?
先ず、Windowsには fork
がないので
lang
1my $pid = fork; 2# forkが失敗した場合はエラー処理を行う 3unless (defined $pid) { 4 die "fork faild."; 5}
は、恐らく無駄でしょう。
上記にある
lang
1system("cmd &")
が、Windowsでは
lang
1system("start cmd")
にあたります。
Windows環境が手元に無いので試せないので、試せないのが恐縮ですが
lang
1system("start", "perl C:/inetpub/wwwroot/data/script/test_001.pl");
や start
のオプションなどでなんとかならないでしょうか。
あとは、動かないと言うのがどういう風に動かないのかが気になります。
動かないと仰っているのは、test_001.pl
の実行結果を待ってしまうと言う事でしょうか?
投稿2015/02/26 03:04
編集2015/02/26 03:21総合スコア42
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

0
start
を使ってみてはいかがでしょう。
lang
1system("start perl C:/inetpub/wwwroot/data/script/test_001.pl");
投稿2015/02/26 02:13
総合スコア42
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。