Perlでファイル出力時にデッドロック(?)してしまいます

このQ&Aのポイント
  • Perl(5.005_03)で、約5000万バイトのテキストファイルを読み込んで、そのデータに変更を加えた後、別のテキストファイルに書き出すプログラムを作っています。
  • テキストファイルへの書き出しは、16回に分けて約300万バイトずつ行っています。
  • ファイルへの書き出しが半分も終わらないうちに、デッドロック(?)してしまうみたいで、書き出し中のファイルは途中のまんま、プログラムが終わってしまいます。いまは、出力ファイルを開く前に「print " ";」を入れることでとりあえず動いています。(それも、どうしてなのかわかりません・・・)何か良い方法はないでしょうか?
回答を見る
  • ベストアンサー

Perlでファイル出力時にデッドロック(?)してしまいます。

Perl(5.005_03)で、約5000万バイトのテキストファイルを読み込んで、そのデータに変更を加えた後、別のテキストファイルに書き出すプログラムを作っています。 テキストファイルへの書き出しは、16回に分けて約300万バイトずつ行っています。 すると、ファイルへの書き出しが半分も終わらないうちに、デッドロック(?)してしまうみたいで、書き出し中のファイルは途中のまんま、プログラムが終わってしまいます。。。 いまは、出力ファイルを開く前に「print " ";」を入れることでとりあえず動いています。(それも、どうしてなのかわかりません・・・) 何か良い方法はないでしょうか? よろしくお願いします。 【環境】sun4-solaris, apache 以下は、ファイルへ書き出している部分のソースです ------------------------------------------------------------------- print " "; # これを入れないとプログラムが正常終了できません open OUT, ">>$file" || die "can't open : $!"; print OUT $data; # $data には約300万バイト入っています close OUT; -------------------------------------------------------------------

  • Perl
  • 回答数3
  • ありがとう数4

質問者が選んだベストアンサー

  • ベストアンサー
  • bubu-chan
  • ベストアンサー率100% (3/3)
回答No.3

約5000万バイトというと、かなり大きなファイルですね。apacheの「Timeout」の設定(httpd.conf)はどうなっていますか?初期値は「300(秒)」になっていると思います。 「print " ";」を入れると正常終了するとのことですので、もしかしたら設定の問題かもしれませんよ。 ファイルの書き込みに300秒以上かかっているのなら、apacheの設定を変更するか、もしくは、定期的にhttpにアクセスしてタイムアウトになるのを防ぐ処理を入れてみてください。

yuyu-chan
質問者

お礼

ありがとうございます! bubu-chanのおっしゃる通り、apacheの設定が原因でした。 助かりました。ありがとうございました♪

その他の回答 (2)

  • tfp
  • ベストアンサー率37% (3/8)
回答No.2

直接関係あるか分かりませんが、 open OUT, ">>$file" || die "can't open : $!"; は、間違いですよ。 これですと、open に失敗した場合でも決して die が実行されることはありません。 Perl5以降 open は、リスト演算子の優先順位を持つので、例え $file が未定義だった場合でも、">>$file" という文字列が偽にならない限り、黙々と処理を進めてしまいます。 ただこの場合、たまたま追記オープンですから分かりづらいかもしれませんが、読み込みオープンで open OUT, "are" || die "can't open : $!"; を試してみれば、are というファイルがないにも関わらず die されないのが分かると思います。 正しく open の戻り値を期待するなら open(OUT, ">>$file") || die "can't open : $!"; と、括弧で囲む必要があります。 もしくは || の代わりにリスト演算子より優先順位の低い or を使ってやれば囲まなくても OKです。 また、close の戻り値もチェックした方が、よいでしょう。

yuyu-chan
質問者

お礼

ありがとうございます。 早速、修正しました。 でも、デッドロックと直接関係はないみたいです。(;_;)

  • alicia-y
  • ベストアンサー率40% (85/208)
回答No.1

もう一つ状況がつかめませんが、 ファイルの先頭に $|=1; を入れたら終了するのかな。 apache って書いて有るので CGI で動かしてるの? perl hogehoge.pl ってやると正常に終了するのかな。

yuyu-chan
質問者

お礼

ご回答ありがとうございます。 PerlはCGIで動かしています。 あと、「$|=1;」も書いているんですが。。。 perl *.pl はまだ試していませんので、試してみます。

関連するQ&A

  • Perlでのファイル入出力、処理方法

    メモ帳で以下のようなプログラムを書きました。(file_1.plで保存しました) #!/usr/bin/perl $file="data.csv"; $cityfile="name.txt"; $outfile="data_out.csv"; open (IN, $file) or die "$!"; open (FILE, $file) or die "$!"; open (OUT, ">$outfile") or die "$!"; @city = <FILE>; ・ ・ ・ これをCygwinコマンド上で、 perl file_1.pl と入力し、Enterを押すと「No such file or directory at file_1.pl line 9.」と表示されます。 line9はopen (FILE, $file) or die "$!";という文です。 どこが間違えで、どのように修正すればよいのでしょうか。 よろしくお願いします。

  • Perlでテキストファイル読み込み

    基本的な質問ですみません。 サーバ上のテキストファイルを読み込んで ローカルのテキストファイルに書き込むというだけなのですが 何度やってもできません。 以下プログラムですが #!usr/bin/perl open(IN,"http://*****/***/***.txt"); $file = <IN>; close(IN); open(OUT,"> a.txt"); print(OUT "$file"); close(OUT); サーバのアドレスは、URLうってみて見れたのでhttp://***(以下略)であってると思います。 サーバのテキストにはchmodで777と権限を与えました。 プログラムに問題あるのでしょうか。 この場合考えられる原因を教えてください。

    • ベストアンサー
    • Perl
  • perlで文書を読み込み検索置換したい

    MAC OS Xを使用しています。 検索置換のプログラムをperで作成し、Applescript上で呼び出したいのです。 実際はファイルメーカーのスクリプトの中でApplescriptを記述してその中で呼び出したいのです。 do shell script "perl ~.pl"という感じで使えるのではないかと 下記のようなサンプルスクリプトを見つけたのですが 内容の更新の仕方がよく分かりません。 perlについては全くの初心者でいろいろ調べたのですがよく理解できませんでした。 検索置換したいのですが、どういうふうに書けばいいのでしょうか。 (2)の部分を教えて下さい。宜しくお願いします。 use strict; use warnings; use File::Copy 'move'; # (1) ファイルの内容を読み込む my $file = 'F:\共有\PERL\test.txt'; open my $fh, '<', $file or die qq/Can't open file "$file": $!/; my $content = do {local $/; <$fh>}; close $fh; # (2) 内容の更新 ▼をリターンに置き換えたいのです。 $line =~s/▼/\n/; # (3) 一時ファイルへの書き出し my $temp_file = "$file.$$." . int(rand 10000); open my $temp_fh, '>', $temp_file or die qq/Can't open file "$file": $!/; print $temp_fh $content; close $temp_fh or die qq/Can't open file "$file": $!/; # (4) 一時ファイル名を元のファイル名に変更 move $temp_file, $file or die qq/Can't move "$temp_file" to "$file": $!/;

  • perlでファイルを分割してファイル名も出力したい

    >AA A AAA aaaaaaaaaaaaaaa aaaaaaaaaaaa >BBB BB B bbbbbbbbbbbbbbb bbbbbbbbbbbbbbb bbbbbbbbbbbbbb ・ ・ こういった形式でテキストが入った大きいサイズのひとつのファイルを ・ファイル名 AA A AAA ・テキスト内 >AA A AAA aaaaaaaaaaaaaaa aaaaaaaaaaaa ・ファイル名 BBB BB B ・テキスト内 >BBB BB B bbbbbbbbbbbbbbb bbbbbbbbbbbbbbb bbbbbbbbbbbbbb となるように個別に出力させたいのですがどのようにすればよいでしょうか? #!/usr/bin/perl -w use strict; my $first; my $file; $first = 1; open(IN,"分割前ファイル"); foreach(<IN>) { if ( /^>(.*)/ ) { if ($first == 0 ) { close(OUT); } else {$first = 0; } $file = $1; $file =~ s/[\r\n]//; open(OUT,">$file"); } else { print OUT $1; print OUT $_; } } close(IN); このようなプログラムを組んだのですが、出力結果はファイル名についてはいいのですが、テキスト内が思ったようにいきません。 ・ファイル名 AA A AAA ・テキスト内 AA A AAAaaaaaaaaaaaaaaa AA A AAAaaaaaaaaaaaa このような結果になってしまいます。 どなたか対処方をわかるかたがいましたらお願いします。

    • ベストアンサー
    • Perl
  • perlプログラム内で中間ファイルを利用するには

    perlプログラムについて 処理1 の アウトプットデータを用いて、処理2を行うというのを1つのperlのプログラム内で実装したいと考えています。 処理1のアウトプットファイルの書き出しに時間がかかり 処理2が先に動き、ファイル読み込みできずに終わってしまいます。 処理1のアウトプットファイル書き出しが終了を待ってから、処理2を実施したいのですが、 どのように記載すればよいのでしょうか? 例) perl program.pl AAA > BBB program.pl 内 open(OUT1,"> program1_work"); open(ARG,$ARGV[0]); while(<ARG>){ 処理1 print OUT1 "XXXXXX"; } close(ARG); open(ARG1,OUT1); while(<ARG1>){ 処理2 print "XXXXXX"; } close(ARG1);

  • perl 計算結果をファイルへ出力したい

    perl やり始めたばかりです。宜しくお願いします。 入力ファイル data.txt があるとします。 data.txt は、 123 456 789 333 555 777 以上のようなテキストファイルといたします。このファイルを 以下の様に100分の1にして出力したい。 1.23 4.56 7.89 3.33 5.55 7.77 と言うことで、この場で教えていただきました。それが、以下です。 #!/usr/bin/perl open(IN, "data.txt") or die ; @x = <IN>; close (IN); foreach $line (@x){ chomp($line); @elms = split(' ',$line); foreach $data (@elms){ print $data/100," "; } print "\n"; } おかげ様でこれはこれで上手く動きました。そこで、出力値をファイルに 書き込みたいのです。 もちろん、以下の様な方法でファイルに 書き込めるのは判っております。 計算プログラム.pl > outfile.txt しかし、上のプログラムをベースにファイルに書き込めないかと色々と 試してはみましたが、どうも上手く行きません。 どなたか教えて頂けないでしょうか? 宜しくお願い申し上げます。

    • ベストアンサー
    • Perl
  • ファイルの出力先の指定

    現在「/var/www/html」内に「fileread.cgi」というプログラムを制作しています。プログラム中で取得したファイルを「/home/mizumaki/download」に保存したいのですがうまくできません。プログラム中で $file="/home/mizumaki/download/index.html" open(OUT,">$file"); print OUT $data; close(OUT); と指定しても保存されません。「/home/mizumaki/download」には保存できないのでしょうか?

  • Perl 教えてください。

    下記のような簡単なスクリプトなんですが、なぜかサーバーにアップすると動きません。 ローカルでコマンドプロンプトから直接実行するとまともに動作します。 パーミッションは「755」と「705」でやってみましたが。 perlのパスは合っていますし、実際同じ場所に置いた他のCGIは動作します。 #!/usr/bin/perl open (DT, "<./data/***/***.csv") or die "File '***.csv' Open Error."; @data = <DT>; $data[0] = ",,,,,,\n"; open (OUT,">./data/***/***1.csv") or die "File '***1.csv' Open Error."; print OUT @data; close (DT); close (OUT); 原因が分からず困っています。 解決策でなく、原因と思えるだけの回答で結構ですので何卒よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • ファイルの読み込みと出力

    ファイルの読み込みと出力 Perl初心者です。よろしくお願いします。 file.csvのようなファイルを読み込んで、 out.csvのように出力するプログラムを作成しているのですが 途中で変な改行が度々入っているためどうしてもうまくいきません。 (file.csvですが、実際は1500行以上あります。 また、最後に必ずendが入っています。 下記のcsvですがテキスト形式で表示した内容です。) 初歩的な質問で申し訳ありません。 調べる限り調べたのですが分かりませんでした。 どうかよろしくお願いします。 「file.csv」 "2010/1/1","C","こんにちは","田中","end", "2009/10/2","B","おはよう","斉藤","end", "2007/3/20","E","Good mor ning","佐藤","end", "1988/8/16","F","こんばんは","中 村","end", "1999/1/10","A","Hello","木村","end", "2005/9/17","D","おはようご ざいます","斎藤","end", 「out.csv」(このように出力したいです) C,こんにちは,田中,2010/1/1,end, B,おはよう,斉藤,2009/10/2,end, E,Good morning,佐藤,2007/3/20,end, F,こんばんは,中村,1988/8/16,end, A,Hello,木村,1999/1/10,end, D,おはようございます,斎藤,2005/9/17,end, 「今書いているプログラムです」 #!/usr/local/bin/perl use strict; use Fatal qw/ open /; my $csv_file = "file.csv"; my @csv = &readCsvFile($csv_file); open(OUT,">out.csv"); for(my $i=0; $i<=5; $i++){    print OUT $csv[$i][1],",";    print OUT $csv[$i][2],",";    print OUT $csv[$i][3],",";    print OUT $csv[$i][0],",";    print OUT $csv[$i][4],","; } close(OUT); sub readCsvFile {    open(DATA, $_[0]);    while(<DATA>) {      chomp;      push @csv, [ split(/",\"/) ];    }    close(DATA);    return @csv; }

    • ベストアンサー
    • Perl
  • perl ファイルが開かない

    perl でファイルを開きたいのですが、なぜか開けません。何がいけないのでしょうか?エラーは、 Name "main::file" used only once: possible typo とでます。エラーを見るかぎり、コードに間違いはなく、apacheかOSに何か原因があるのではないかとおもうのですが、悩んでいます。OSはubuntuです。 #!/usr/bin/perl -w open (IN, "<test.txt") or die ("Could not open $file: $!"); while(<IN>) { print "$_"; } close (IN);