問題: scriptA.cgi正處於一個無限循環並處理一個打開的套接字到一個Flash客戶端。 scriptB.cgi從網絡中調用,做它需要做的事情,然後需要通知scriptA向客戶端發送消息。如何調用已經從另一個腳本運行的perl進程?
這可能嗎?我被困在如何讓scriptB識別坐在那裏與套接字連接的scriptA的實例,而不是啓動它自己的一個。
所有的想法讚賞。
問題: scriptA.cgi正處於一個無限循環並處理一個打開的套接字到一個Flash客戶端。 scriptB.cgi從網絡中調用,做它需要做的事情,然後需要通知scriptA向客戶端發送消息。如何調用已經從另一個腳本運行的perl進程?
這可能嗎?我被困在如何讓scriptB識別坐在那裏與套接字連接的scriptA的實例,而不是啓動它自己的一個。
所有的想法讚賞。
如果通信需求很簡單,這是一個很好的信號應用。
編輯存儲來自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
。執行的線程將會恢復,腳本可以使用這些信息。
有腳本存儲它的pid somwhere(在一個帶有某種id的db中),然後scriptB可以在db中查找pid併發送一個信號給scriptA。
編輯:
答題要求在評論
進程的PID可以使用內建皮爾斯變量$$或$ PID或找到$ PROCESS_ID取決於你的Perl有多老。
有關詳細信息,請參閱perlvar。
我希望這是你在哪裏尋找的ID。如果沒有,你必須找到一種方法來分離不同的scriptA實例。 (也許通過會話ID或套接字,在這裏我不能幫你進一步)
scriptA如何獲得其ID? – 2009-12-29 23:26:06
編輯答案以提供更多信息。 – Nifle 2009-12-29 23:35:06
其他人已經提到如何獲得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.
確實非常有用。感謝(並歡迎SO :) :) – 2009-12-30 00:52:32
我很想回答,「發信號」或「使用一些但是,更容易和可擴展的方法是使用所有腳本可以與之交談的sqlite(或其他)數據庫,
ScriptA.cgi將通過執行類似'SELECT事件來自事件WHERE clientID =?'。
ScriptB.cgi只會將一行插入具有正確clientID的事件表中。
這樣可以避免所有'找到pid'混亂,並且也意味着您不會獲得使用命名管道獲得的阻塞IO問題或者一個腳本崩潰。
我已經有一個數據庫在混合,但我不確定這種方法是理想的,因爲那麼正在被髮信號的過程將需要每100毫秒搗棒尋找一個提示做任何它應該做的事情。 – 2009-12-31 19:23:10
編輯我的答案提供更多信息。 – Nifle 2009-12-29 23:36:06
很酷...所以我唯一不清楚的就是如何實際調用正在運行的進程。假設我有自己的ID,我該如何撥打該腳本?理想情況下,我可以調用腳本中的一個方法。我甚至不需要傳遞參數,我只需要它就可以知道是時候醒來工作了。 – 2009-12-29 23:52:48
請參閱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