问题: scriptA.cgi处于无限循环中并处理打开的套接字到Flash客户端。 scriptB.cgi从Web调用,执行它需要做的事情,然后需要通知scriptA向客户端发送消息。
这可能吗?我一直坚持如何让scriptB识别坐在那里的socketA实例,而不是启动它自己的一个。
所有的想法都很受欢迎。
答案 0 :(得分:5)
如果通信需求很简单,这是一个很好的信号应用。
已编辑以存储来自scriptA的进程ID并在scriptB中读取它 - 脚本A和B必须就名称达成一致。
# script B
do_scriptB_job();
if (open(my $PID_FILE, "<", "scriptA.pid.file")) {
$process_id_for_scriptA = <$PID_FILE>;
close $PID_FILE;
kill 'USR1', $process_id_for_scriptA; # makes scriptA run the SIGUSR1 handler
}
# script A
open(my $PID_FILE, ">", "scriptA.pid.file");
print $PID_FILE $$;
close $PID_FILE;
my $signaled = 0;
$SIG{"USR1"} = \sub { $signaled = 1 } # simple SIGUSR1 handler, set a variable
while ( in_infinite_loop ) {
if ($signaled) {
# this block runs only if SIGUSR1 was received
# since last time this block was run
send_a_message_to_the_client();
$signaled = 0;
} else {
do_something_else();
}
}
unlink "scriptA.pid.file"; # cleanup
当脚本A收到SIGUSR1
信号时,脚本将被中断以运行USR1
信号处理程序,设置$signaled
。然后执行线程将恢复,脚本可以使用该信息。
答案 1 :(得分:2)
让scriptA存储它的pid somwhere(在带有某种id的db中),然后scriptB可以在db中查找pid并向scriptA发送信号。
编辑:
在评论中回答问题
使用perls内置变量 $$ 或 $ PID 或 $ PROCESS_ID 可以找到该过程的pid,具体取决于perl的年龄是
有关详细信息,请参阅perlvar。
我希望这是你在寻找的ID。如果不是,您将不得不找到一种方法来分隔不同的scriptA实例。 (也许是通过会话ID或套接字。这里我不能再帮助你了)
答案 2 :(得分:2)
其他人已经提到了如何获取PID(如果你没有自己fork()它,只需让其他进程写它......某处......两个进程都知道如何获取它。或者走路进程表,但这是一个可怕的解决方案,并且在单例之外完全不可扩展。)
由于您注意到欢迎任何想法,请注意perldoc perlipc
解释了您可能用于实际沟通的各种机制:
NAME
perlipc - Perl interprocess communication (signals, fifos, pipes, safe
subprocesses, sockets, and semaphores)
DESCRIPTION
The basic IPC facilities of Perl are built out of the good old Unix
signals, named pipes, pipe opens, the Berkeley socket routines, and SysV
IPC calls. Each is used in slightly different situations.
答案 3 :(得分:0)
答案 4 :(得分:0)
我很想回答,“发送信号”或“使用某种IPC在应用程序之间进行交谈”但是,更容易和可扩展的方法是使用所有脚本都可以与之交谈的sqlite(或其他)数据库,
ScriptA.cgi会通过执行“SELECT event FROM events WHERE clientID =?”之类的操作来轮询数据库。
ScriptB.cgi只需在具有正确clientID的事件表中插入一行。
这样可以避免所有'找到pid'的混乱,也意味着你不会遇到使用命名管道或者如果一个脚本崩溃的阻塞IO问题。