Perl1:$SIG{'USR1'} = sub {動かしたいスクリプト};sleep(待つ時間);
Perl2:kill 'USR1',プロセス番号
今はこのようにして、Perl2がPerl1に「動作していいよ!」というように連絡しているのですが・・・、Speedyperlなどの下では、プロセスを1つ1つ作らないため、この方法は上手く動きません。
なんとかして上記のような通信を動かす方法を教えてください。
ただし、$SIGは使用しない方法でお願いします。
また、Speedyperl以外を使用したり、Speedyperlの起動プロセス数MAXを1にしたりする方法は除きます。
具体的な方法でよろしくお願いします。
横から失礼。既存のスクリプトをちょっとイジって実現してみました。
UDPを使ってみましたが、SpeedyCGIで動作確認してないですけど、動きますかね?
・スクリプトA
1 #!/usr/bin/perl 2 3 use IO::Socket; 4 use IO::Select; 5 6 $udpSock = IO::Socket::INET->new( 7 Proto => "udp", 8 LocalPort => 32999, 9 ); 10 11 $udpSel = IO::Select->new; 12 $udpSel->add($udpSock); 13 14 if(IO::Select->select($udpSel, undef, undef, 60)) { # sleep 60 15 print "get " . <$udpSock>; 16 } else { 17 print "timeout...\n"; 18 }
・スクリプトB
1 #!/usr/bin/perl 2 3 use IO::Socket; 4 5 my $udpSock = IO::Socket::INET->new( 6 Proto => "udp", 7 PeerAddr => "localhost", 8 PeerPort => 32999, 9 ); 10 11 print $udpSock "Trigger\n"; # 連絡
Speedyperl というのは SpeedyCGI のことでしょうか?
SIGNAL ではダメな理由がよく分からなかったのですが。
TCP/IP や Unix-Domain ソケット、SysV IPC を使ってみてはいかがでしょうか?
あ、SpeedyCGIですね。うーん、表現力がないので上手く説明できないのですが(苦笑)
私の使用目的上、1つのプロセスで複数のスクリプトを動作させるとダメなんです・・・。抽象的ですみません。
説明が足りなかったので追記します。
PerlスクリプトA・・・sleep(60);等で待機
PerlスクリプトB・・・PerlスクリプトAに連絡
PerlスクリプトA・・・連絡を受けたので、すぐにsleepをやめてスクリプトを全て実行する
このようなことをしたいのです。
どうやってその連絡をするか・・・・・。
ファイルを用意して、そのファイルが(Bによって)書き換えられたら(Aの待機しているスクリプトを)実行のような形でもいいのですが、そのためにはsleep(1);を繰り返したりでファイルを監視する必要があります。
この場合ですと、最大1秒のタイムラグができます。
なるべく(CPU負荷の低い方法で)リアルタイムを実現したいのです。
横から失礼。既存のスクリプトをちょっとイジって実現してみました。
UDPを使ってみましたが、SpeedyCGIで動作確認してないですけど、動きますかね?
・スクリプトA
1 #!/usr/bin/perl 2 3 use IO::Socket; 4 use IO::Select; 5 6 $udpSock = IO::Socket::INET->new( 7 Proto => "udp", 8 LocalPort => 32999, 9 ); 10 11 $udpSel = IO::Select->new; 12 $udpSel->add($udpSock); 13 14 if(IO::Select->select($udpSel, undef, undef, 60)) { # sleep 60 15 print "get " . <$udpSock>; 16 } else { 17 print "timeout...\n"; 18 }
・スクリプトB
1 #!/usr/bin/perl 2 3 use IO::Socket; 4 5 my $udpSock = IO::Socket::INET->new( 6 Proto => "udp", 7 PeerAddr => "localhost", 8 PeerPort => 32999, 9 ); 10 11 print $udpSock "Trigger\n"; # 連絡
おおおおおおおおおおおおお
わざわざスクリプトまで書いていただいてすみません><
素晴らしい!一度動かしてみたいとおもいます。
1)共有メモリ、セマフォを使う
http://www.nkozawa.com/html/TipsProgPerl.html
2)スレッドを使う
3)TCP/IPで通信する
(例)
------------------------------
【Perl1(サーバー)側】
use IO::Socket::INET;
my $PORT = 10000; # 任意の空いているポート番号
my $server = IO::Socket::INET->new(LocalPort => $PORT,
Type => SOCK_STREAM,Reuse -> 1,
Listen => 1); # 接続最大数=1
$server->accept();
close($server);
### '動作していいよ!'サインを受け取った後のPerl1の処理
------------------------------
【Perl2(クライアント)側】
use IO::Socket::INET;
#### '動作していいよ!'サインを出すまでのPerl2の処理
my $PORT = 10000; # Perl1に合わせる
my $socket = IO::Socket::INET->new(@localhost:$PORT");
print $socket '動作していいよ!';
close($socket);
------------------------------
ただしこの方法は、Perl1:Perl2のペアが複数発生する場合、衝突しない複数ポート番号の管理が必要となります。
3)親子プロセスを使う
(例)
if (fork())
{
wait;
#### '動作していいよ!'サインを受け取った後のPerl1の処理
} else {
#### '動作していいよ!'サインを出すまでのPerl2の処理
}
exit;
はてなの人が優しすぎて感動しています。
本当にありがとうございます。
いったん既存のスクリプトに導入してみて、動かしてみますね。
(追記)
みなさんありがとうございました!
2番さんの回答を既存のスクリプトに導入しました。
快調に動作しています。
おおおおおおおおおおおおお
わざわざスクリプトまで書いていただいてすみません><
素晴らしい!一度動かしてみたいとおもいます。