tweeeetyのぶろぐ的めも

アウトプットが少なかったダメな自分をアウトプット<br>\(^o^)/

ファイルディスクリプタをperlで見てみたいときメモ

はじめに

ディスクリプタがなにか?とか、ファイルハンドルの概念とは?とかっていう話ではないです。
純粋に見てみたいだけのメモですw

特にperlが実行されるプロセスで何回もファイルオープンしたら
何回もディスクリプタが作られるところを見たいというメモです

fileno(ファイルディスクリプタを得る)

前置きですが、perlでファイルディスクリプタを得たいときの関数

fileno(ファイルハンドル)

http://perl-cgi.net/function/fileno/

試し最初

ということなので、まずはこんな感じに見てみます
perl file_descriptor_test.pl

open ( my $fh, '<', './input.txt' ) or die $!;
print fileno $fh;
close $fh;

結果

# perl perl file_descriptor_test.pl
3 at file_descriptor_test.pl line 4.

ふむふむ。

何回も開いて何回も作られるか見てみる

意外にすんなりうまくいかなかったので失敗パターンと成功パターンをメモ

失敗1

単純に5回開いてみる
perl file_descriptor_test.pl

for(1..5)
{
  open ( my $fh, '<', './input.txt' ) or die $!;
  print fileno $fh;
  print "\n";
  close $fh;
}

結果

# perl perl file_descriptor_test.pl
3
3
3
3
3

なんとなくは想像してましたけど、closeしてるので空いたファイルディスクリプタ(今回は3)を使う?ようです

失敗2

単純に5回開いてみる+closeしない
perl file_descriptor_test.pl

for(1..5)
{
  open ( my $fh, '<', './input.txt' ) or die $!;
  print fileno $fh;
  print "\n";
  #close $fh;
}

結果

# perl perl file_descriptor_test.pl
3
3
3
3
3

closeしなくてもダメみたいです

成功1

5回開いてみる+配列に入れてみる+closeしない
perl file_descriptor_test.pl

my @fhs;
for(1..5)
{
  open ( my $fh, '<', './input.txt' ) or die $!;
  push @fhs, $fh;
  print fileno $fh;
  print "\n";
  #close $fh;
}

結果

# perl perl file_descriptor_test.pl
3
4
5
6
7

うまくいきました。

ついでにsleep 30を入れてスクリプトが終わらないようにし、その間のにつかみっぱのファイルディスクリプタも確認してみます。

5回開いてみる+配列に入れてみる+closeしない+sleepする
perl file_descriptor_test.pl

my @fhs;
for(1..5)
{
  open ( my $fh, '<', './input.txt' ) or die $!;
  push @fhs, $fh;
  print fileno $fh;
  print "\n";
  #close $fh;
}
sleep 30;

結果

# perl perl file_descriptor_test.pl
3
4
5
6
7

# ps aux | grep perl
hoge    2800  0.0  0.0  77836  1524 pts/5    S+   19:00   0:00 perl file_descriptor_test.pl

# ls -l /proc/2800/fd/
lrwx------ 1 hoge hoge 64 12月 20 19:01 0 -> /dev/pts/5
lrwx------ 1 hoge hoge 64 12月 20 19:01 1 -> /dev/pts/5
lrwx------ 1 hoge hoge 64 12月 20 19:00 2 -> /dev/pts/5
lr-x------ 1 hoge hoge 64 12月 20 19:01 3 -> /home/hoge/test_perl/file_descriptor_test/input.txt
lr-x------ 1 hoge hoge 64 12月 20 19:01 4 -> /home/hoge/test_perl/file_descriptor_test/input.txt
lr-x------ 1 hoge hoge 64 12月 20 19:01 5 -> /home/hoge/test_perl/file_descriptor_test/input.txt
lr-x------ 1 hoge hoge 64 12月 20 19:01 6 -> /home/hoge/test_perl/file_descriptor_test/input.txt
lr-x------ 1 hoge hoge 64 12月 20 19:01 7 -> /home/hoge/test_perl/file_descriptor_test/input.txt

なるほどーー

ついでに失敗3

5回開いてみる+配列に入れてみる+closeする
perl file_descriptor_test.pl

my @fhs;
for(1..5)
{
  open ( my $fh, '<', './input.txt' ) or die $!;
  push @fhs, $fh;
  print fileno $fh;
  print "\n";
  close $fh;
}
sleep 30;

結果

# perl perl file_descriptor_test.pl
3
3
3
3
3

やっぱりcloseするとダメですね。

成功2

5回開いてみる+ファイルハンドルを複数作ってやる
perl file_descriptor_test.pl

for(1..5)
{
  my $fh = "FH$_";
  open ${$fh}, '<', './input.txt' or die "Can't open file: $!";
  print fileno ${$fh};
  print "\n";
}

結果

# perl perl file_descriptor_test.pl
3
4
5
6
7

こちらもうまく行きました。
型グロブとかも使えばできるかなーと思ってやったけどできなかった。。。perlの勉強が必要ですね(><)

まとめ

ってことで
特に得るものは無いメモかもですが、正解に行くまでに結構ハマってしまったのでメモっときましたw

ちなみにファイルディスクリプタについてはこちらで勉強させてもらいました
ファイルディスクリプタ(file descriptor)について調べてみた
Perlにおけるファイルハンドルの概念を理解する
理解したようなしてないような…むずかしい(><)