2009-12-29 29 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

相關問題