2009-12-29 56 views
3

问题: scriptA.cgi正处于一个无限循环并处理一个打开的套接字到一个Flash客户端。 scriptB.cgi从网络中调用,做它需要做的事情,然后需要通知scriptA向客户端发送消息。如何调用已经从另一个脚本运行的perl进程?

这可能吗?我被困在如何让scriptB识别坐在那里与套接字连接的scriptA的实例,而不是启动它自己的一个。

所有的想法赞赏。

+1

编辑我的答案提供更多信息。 – Nifle 2009-12-29 23:36:06

+0

很酷...所以我唯一不清楚的就是如何实际调用正在运行的进程。假设我有自己的ID,我该如何拨打该脚本?理想情况下,我可以调用脚本中的一个方法。我甚至不需要传递参数,我只需要它就可以知道是时候醒来工作了。 – 2009-12-29 23:52:48

+0

请参阅mobrules回答http://stackoverflow.com/questions/1977462/how-do-i-call-a-perl-process-that-is-already-running-from-another-script/1977516#1977516为短例。如果你想进一步的建议,我建议问一个新的问题。类似于*“如何使用perl发送和接收信号?”* – Nifle 2009-12-30 00:01:42

回答

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。执行的线程将会恢复,脚本可以使用这些信息。

+0

您没有解决这个问题:*我被困在如何让scriptB识别坐在那里的socketA连接的scriptA的实例,这个套接字* – Nifle 2009-12-29 23:18:18

+0

是的......这实际上是我失去了一部分...一旦我有了,我可以弄清楚其余部分。 – 2009-12-29 23:25:35

+0

编辑后+1。使用上述信号的 – Nifle 2009-12-30 00:04:10

2

有脚本存储它的pid somwhere(在一个带有某种id的db中),然后scriptB可以在db中查找pid并发送一个信号给scriptA。

编辑:
答题要求在评论

进程的PID可以使用内建皮尔斯变量$$$ PID或找到$ PROCESS_ID取决于你的Perl有多老。

有关详细信息,请参阅perlvar

我希望这是你在哪里寻找的ID。如果没有,你必须找到一种方法来分离不同的scriptA实例。 (也许通过会话ID或套接字,在这里我不能帮你进一步)

+0

scriptA如何获得其ID? – 2009-12-29 23:26:06

+0

编辑答案以提供更多信息。 – Nifle 2009-12-29 23:35:06

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. 
+1

确实非常有用。感谢(并欢迎SO :) :) – 2009-12-30 00:52:32

0

我很想回答,“发信号”或“使用一些但是,更容易和可扩展的方法是使用所有脚本可以与之交谈的sqlite(或其他)数据库,

ScriptA.cgi将通过执行类似'SELECT事件来自事件WHERE clientID =?'。

ScriptB.cgi只会将一行插入具有正确clientID的事件表中。

这样可以避免所有'找到pid'混乱,并且也意味着您不会获得使用命名管道获得的阻塞IO问题或者一个脚本崩溃。

+0

我已经有一个数据库在混合,但我不确定这种方法是理想的,因为那么正在被发信号的过程将需要每100毫秒捣棒寻找一个提示做任何它应该做的事情。 – 2009-12-31 19:23:10

相关问题