These pages are written by only Japanese.
|
Namazu for hns による簡易全文検索です。 詳細は 詳細指定/ヘルプをご参照下さい。 |
|||||||||||||||||||||||||||||||||||||||||||||
bash-2.05$ uptime 6:55AM up 1 day, 11:21, 1 user, load averages: 6.42, 6.18, 6.02という状況では、バックアップ作業さえキャプチャーに悪影響を及ぼします。
親に先立ち子プロセスが死んだ場合は、子プロセスは水子(ゾンビ)として 自縛霊のようにプロセステーブルを占有して、親に (wait という) お経を唱えてもらうまで成仏できません。お経 (wait) を忘れて、短命な子プロセスを生成し続ける無責任な親がいると、 プロセステーブルがゾンビで溢れて新たなプロセスが生成できなくなり、 (一般ユーザでは)ログインさえ出来なくなります。
$SIG{'CHLD'} = sub { wait(); };といったコードを追加していますが、 それだけでは問題が生じる事があります。なぜなら、
このようにすれば、$SIG{'CHLD'} = sub { while(wait3() > 0) { } };use POSIX ":sys_wait_h"; $SIG{'CHLD'} = sub { shift; while(waitpid(-1,&WNOHANG)> 0) { } };
POSIX では SIG_IGN に SIGCLD をセットした時の振舞いは規定されていないので、 POSIX 系をサポー トするようなプログラムには使うことができません。とありますので、今のところ、SIGCHLD でSIG_IGN を利用せず、 自前でハンドラを用意する事にしています。
signal(SIGPIPE, SIG_IGN);デバッグをしていて気付いたのですが、 gdb でプロセスを動かすと、ハンドラに飛ばずにプロセスがいきなり 終了してしまいます。これは gdb の仕様なのでしょうか…
extern int server_open(int port); #define BASE_PORT 8480 int max_sockfd = -1; for (i=0; i<n_input; i++ ) { sockfds[i] = server_open(BASE_PORT + inputs[i]); if (max_sockfd < sockfds[i]) max_sockfd = sockfds[i]; }
extern int server_accept(int sockfd); extern int server_file2net(int sockfd, char *filename); while(keep_running) { fd_set readfds; int n; # read enable 監視対象の fd を決める FD_ZERO(&readfds); for(i=0; i<n_input; i++) { FD_SET(sockfds[i], &readfds); } # 上記で設定した fd のいずれかが read enable になるまで待つ n = select(max_sockfd + 1, &readfds, NULL, NULL, &timeout); if (n < 0) { perror("seleect failed"); return EXIT_FAILURE; } if (n == 0) { printf("may be timeout\n"); } # 実際に read enable の fd を調べる for(i=0; i<n_input; i++) { if (FD_ISSET(sockfds[i], &readfds)) { int cfd; # accept して接続を確立する cfd = server_accept(sockfds[i]); <キャプチャ処理& jpeg 圧縮> # jpeg データをクライアントに送信 server_file2net(cfd, jpeg_filename); close(cfd); } } }このようなコードを追加しました。
failure while saving jpeg rename: No such file or directoryのエラーが発生する現象に見舞われました。
bktrclient <サーバ名> <ビデオ入力番号> <出力ファイル名>コードのイメージを以下に示します。
int input, port; int sockfd; char *server_name; server_name = argv[1]; input = atoi(argv[2]); filename = argv[3]; sockfd = client_open(server_name, port); client_net2file(sockfd, filename); close(sockfd);
my $base_dir = "〜/htdocs"; my %old_dir; while(1) { my ($dir_time, $file_time) = make_dir_time(time()); foreach my $input (0 .. 1) { my $dir = $base_dir . $input .'/' .$dir_time; `mkdir -p $dir`; `bktrclient -f $dir/$file_time -s $input`; # 次のディレクトリに処理が移った時、 # 前のディレクトリで mkthum の処理を行う。 if (exists($old_dir{$input})) { if ($old_dir{$input} ne $dir) { my $pid = fork(); ## be careful !! if ($pid == 0) { `cd $old_dir{$input} ; mkthum.pl -l 6 -r 10`; exit 0; } $old_dir{$input} = $dir; } } else { $old_dir{$input} = $dir; } } sleep(1); }
use Time::HiRes; my $start_time = Time::HiRes::time; my $time_index = 0; while(1) { <処理> $time_index++; my $diff_time = Time::HiRes::time - $start_time; my $wait_time = $time_index - $diff_time; if ($wait_time > 0) { select(undef, undef, undef, $wait_time); } }これで、一秒置きに処理してくれる…はずでしたが、 一秒+αの間隔で処理しています。