2020国产成人精品视频,性做久久久久久久久,亚洲国产成人久久综合一区,亚洲影院天堂中文av色

分享

php進程后臺調(diào)用(多線程/進程)

 Ralf_Jones 2007-05-29

php進程后臺調(diào)用

這兩天在研究php模擬多線程的問題,碰到一個問題就是無論exec、popen、還是proc_open都會造成等待,也就是阻塞式的調(diào)用,而我想要得是無阻塞的調(diào)用,讓程序在后臺執(zhí)行就可以解決問題,搜索之后找到了解決辦法:

<?php
/* Note that the call itself isn‘t sanitized in any way, so it‘s
important to make sure that this can‘t be exploited, see
docs for escapeshellcmd() for details
*/
// Demonstration
if(launchBackgroundProcess(‘touch testfile.txt‘)){
print ‘Successfully launched background process‘;
}
/**
* Launch Background Process
*
* Launches a background process (note, provides no security itself, $call must be sanitized prior to use)
* @param string $call the system call to make
* @author raccettura
*/
function launchBackgroundProcess($call) {
// Windows
if(is_windows()){
pclose(popen(‘start /b ‘.$call.‘‘, ‘r‘));
}
// Some sort of UNIX
else {
pclose(popen($call.‘ /dev/null &‘, ‘r‘));
}
return true;
}
/**
* Is Windows
*
* Tells if we are running on Windows Platform
* @author raccettura
*/
function is_windows(){
if(PHP_OS == ‘WINNT‘ || PHP_OS == ‘WIN32‘){
return true;
}
return false;
}
?>

關鍵在于

‘ /dev/null &‘

(*nix下的后臺運行方式)

‘start /b ‘

(windows下的后臺運行方式)

想了一下,似乎很多腳本都可以用這種方式將一些操作移交后臺進行,可以大幅提高效率。

如果要返回結果,則可以用異步執(zhí)行并返回狀態(tài)的方式,邊處理邊顯示處理結果,這可以用在一些耗時較長的操作上,比如論壇備份\恢復等:

<?php
/****
* Again notice this is unsanitized since we trust ourselves.  Coming from the web
* it would need to be sanitized to ensure it‘s safe to use.  see escapeshellarg()
****/
$hostname = ‘a(chǎn)ccettura.com‘;
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www./TR/xhtml11/DTD/xhtml11.dtd">
<HTML xmlns="http://www./1999/xhtml">
<head>
<title>Traceroute to $hostname</title>
</head>
<body>
<?php
if(is_windows()){
$cmd = ‘tracert -w 10‘;
} else {
$cmd = ‘traceroute -w 10‘;
}
$handle = popen("$cmd $hostname 2>&1", ‘r‘);
while(!feof($handle)) {
$buffer = fgets($handle);
$buffer = ‘<p>‘.trim(htmlspecialchars($buffer)).‘</p>‘;
echo $buffer;
ob_flush();
flush();
}
pclose($handle);
/**
* Is Windows
*
* Tells if we are running on Windows Platform
* @author raccettura
*/
function is_windows(){
if(PHP_OS == ‘WINNT‘ || PHP_OS == ‘WIN32‘){
return true;
}
return false;
}
?>
</body>
</html>
 

繼續(xù)php多線程/進程的問題

昨天找到了進程后臺運行的方法,今天測試了一下,發(fā)現(xiàn)popen的速度很慢,要40-50毫秒,exec更慢!類似的程序調(diào)用命令,都要經(jīng)過系統(tǒng)調(diào)用,每次都開啟一個php進程想必很慢。

比較笨的辦法還是用fsockopen去通過http在server端get,試了一下,這樣不會慢,缺點是增加了apache負載,每個請求都要在后臺再請求一次。

我寫了段腳本test.php,用fsockopen循環(huán)連接本地另外一個腳本test1.php,不做任何操作立即關閉連接,test1.php每次在文本文件test.cache中寫入一行,循環(huán)100次的時候執(zhí)行很快,test.cache中也正確的記錄了100行。當循環(huán)1000次的時候,問題就來了,test.php執(zhí)行了21.6888360977秒,也就是21秒內(nèi)向apache發(fā)了1000個請求連test1.php,系統(tǒng)馬上沒有響應了,內(nèi)存占用飆升到1G多,一分鐘之后才恢復正常。test.cache中丟失63行,可能是由于apache超載造成的,但是系統(tǒng)內(nèi)存卻始終沒有降下來,apache的占用了83M,剩下的不知道怎么回事- -
最后又找了半天,找到了fork實現(xiàn)的真正多線程!fork是pcntl(Process Control Functions)下的一個函數(shù),pcntl只支持*nix系統(tǒng),目前沒有windows下的相關模塊。(文檔中說需要在編譯php時--enable-pcntl,我用phpize編譯成php模塊的方式,通過在php.ini中添加extension=pcntl.so也可以使用。)


php手冊里面就有了,但是在網(wǎng)上幾乎找不到中文的文檔!文檔里面有這樣一個實例:

<?php
declare(ticks=1);
echo "I‘m going to be a Dad.n";
if (spawn_child(‘child_function‘)) {
echo ‘Parent pid:‘.posix_getpid()."n";
}
echo "I‘m going to be a Dad again!.n";
if (spawn_child(‘child_function‘,1,2,3,4)) {
echo ‘Child - 2 Parent pid:‘.posix_getpid()."n";
}
echo "What you‘re pregnant again!?.n";
if (spawn_child(‘grand_children‘)) {
echo ‘Child - 3 Parent pid:‘.posix_getpid()."n";
}
function grand_children() {
echo "Dad I‘m going to have a baby.n";
spawn_child(‘child_function‘,‘Joe‘);
echo "I‘m so proud of my kids.n";
}
function spawn_child($function) {
$original_pid = posix_getpid();
$pid = pcntl_fork();
if ($pid == -1) {
die ("Unable to spawn childn");
}
$new_pid = posix_getpid();
if ($new_pid == $original_pid) {
return true;
}
if (function_exists($function)) {
$numargs = func_num_args();
if ($numargs > 1) {
$args = func_get_args();
//print_r ($args);
unset($args[0]);
call_user_func($function,$args);
} else {
call_user_func($function);
}
echo "Done with child ".$new_pid." they moved out.n";
exit;
} else {
die ("$function does not existn");
}
}
function child_function() {
echo ‘Child pid:‘.posix_getpid()."n";
$args = func_get_args();
if (!empty($args))
print_r ($args);
}
pcntl_wait( $status);
?>

用pcntl實現(xiàn)的多線程可以解決很多問題了,但是似乎還是不能解決我的問題。在多線程雖然可以讓程序并行執(zhí)行,但所有的程序仍然在前臺完成,在所有的線程完成之前,瀏覽器仍然會顯示載入狀態(tài)。在這種狀態(tài)下,javascript代碼不會執(zhí)行,而我正是需要php產(chǎn)生一段javascript腳本,我想我的目的可能不是多線程或者并發(fā)處理,而是異步調(diào)用、后臺執(zhí)行,讓生成腳本之外的操作在后臺執(zhí)行。
所以我的這種情況用最開始的fsockopen()方法可能更有效,但是fsockopen是不能進行異步處理的,如果要跟打開的連接進行交互,就沒有任何優(yōu)勢可言了。不過我在網(wǎng)上找到了可以進行異步通信的辦法,其實是變相的實現(xiàn)了多線程:php多路復用(多線程)[翻譯]

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多