问题: scriptA.cgi 处于无限循环中并处理 Flash 客户端的打开套接字。 scriptB.cgi 从网络调用,执行它需要执行的操作,然后需要通知 scriptA 向客户端发送消息。
这可能吗?我被困在如何让 scriptB 识别与套接字连接在一起的 scriptA 实例,而不是启动它自己的实例。
所有想法均表示赞赏。
如果通讯需求简单,这是一个很好的信号应用。
编辑以存储脚本A中的进程ID并在脚本B中读取它——脚本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
。然后执行线程将恢复,脚本可以使用该信息。
让 scriptA 将其 pid 存储在某个位置(在具有某种 id 的数据库中),然后 scriptB 可以在数据库中查找 pid 并向 scriptA 发送信号。
编辑:
回答评论中提出的问题
可以使用 perls 内置变量 $$ 或 $PID 或 $PROCESS_ID 找到进程的 pid,具体取决于你的 perl 的年龄。
有关详细信息,请参阅perlvar。
我希望这是您要找的 ID。如果没有,您将必须找到一种方法来分隔不同的 scriptA 实例。 (也许通过会话ID,或者套接字。在这里我无法进一步帮助你)
其他人提到了如何获取 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.
我很想回答“发送信号”或“使用某种 IPC 在应用程序之间进行通信”,但是,一种更简单且可扩展的方法是使用所有脚本都可以与之通信的 sqlite(或其他)数据库,
ScriptA.cgi 会通过执行“SELECT event FROM events WHERE clientID=?”之类的操作来轮询数据库。
ScriptB.cgi 只需将一行插入具有正确 clientID 的事件表中。
这避免了所有“查找 pid”的混乱,也意味着您不会遇到命名管道或某个脚本崩溃时出现的阻塞 IO 问题。
域套接字:Unix 域 TCP 客户端和服务器