无码一区二区三区高清在线观-无码一区二区三区高清在线-无码一区二区三区电影-无码一区二区三区不卡av-无码一区二区三区不卡-无码一区二区三区va在线播放

首頁 > 職業(yè)資格  > 

PHP多線程的實現方法

2023-05-23   來源:萬能知識網

PHP多線程的實現方法


(資料圖)

多線程是java中一個很不錯的東西,很多朋友說在php中不可以使用PHP多線程了,其實那是錯誤的說法PHP多線程實現方法和fsockopen函數有關,下面我們來介紹具體實現程序代碼,有需要了解的同學可參考。

當有人想要實現并發(fā)功能時,他們通常會想到用fork或者spawn threads,但是當他們發(fā)現php不支持多線程的時候,大概會轉換思路去用一些不夠好的語言,比如perl。

其實的是大多數情況下,你大可不必使用 fork 或者線程,并且你會得到比用 fork 或 thread 更好的性能。

假設你要建立一個服務來檢查正在運行的n臺服務器,以確定他們還在正常運轉。你可能會寫下面這樣的代碼:

代碼如下

$hosts = array("host1.sample.com", "host2.sample.com", "host3.sample.com");

$timeout = 15;

$status = array();

foreach ($hosts as $host) {

$errno = 0;

$errstr = "";

$s = fsockopen($host, 80, $errno, $errstr, $timeout);

if ($s) {

$status[$host] = "Connectedn";

fwrite($s, "HEAD / HTTP/1.0rnHost: $hostrnrn");

do {

$data = fread($s, 8192);

if (strlen($data) == 0) {

break;

}

$status[$host] .= $data;

} while (true);

fclose($s);

} else {

$status[$host] = "Connection failed: $errno $errstrn";

}

}

print_r($status);

?>

它運行的很好,但是在fsockopen()分析完hostname并且建立一個成功的連接(或者延時$timeout秒)之前,擴充這段代碼來管理大量服務器將耗費很長時間。

因此我們必須放棄這段代碼;我們可以建立異步連接-不需要等待fsockopen返回連接狀態(tài)。PHP仍然需要解析hostname(所以直接使用ip更加明智),不過將在打開一個連接之后立刻返回,繼而我們就可以連接下一臺服務器。

有兩種方法可以實現;PHP5中可以使用新增的stream_socket_client()函數直接替換掉fsocketopen()。PHP5之前的版本,你需要自己動手,用sockets擴展解決問題。

下面是PHP5中的解決方法:

它運行的很好,但是在fsockopen()分析完hostname并且建立一個成功的連接(或者延時$timeout秒)之前,擴充這段代碼來管理大量服務器將耗費很長時間。

因此我們必須放棄這段代碼;我們可以建立異步連接-不需要等待fsockopen返回連接狀態(tài)。PHP仍然需要解析hostname(所以直接使用ip更加明智),不過將在打開一個連接之后立刻返回,繼而我們就可以連接下一臺服務器。

有兩種方法可以實現;PHP5中可以使用新增的.stream_socket_client()函數直接替換掉fsocketopen()。PHP5之前的版本,你需要自己動手,用sockets擴展解決問題。

下面是PHP5中的解決方法:

代碼如下

$hosts = array("host1.sample.com", "host2.sample.com", "host3.sample.com");

$timeout = 15;

$status = array();

$sockets = array();

/* Initiate connections to all the hosts simultaneously */

foreach ($hosts as $id => $host) {

$s = stream_socket_client("

$

$host:80", $errno, $errstr, $timeout,

STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT);

if ($s) {

$sockets[$id] = $s;

$status[$id] = "in progress";

} else {

$status[$id] = "failed, $errno $errstr";

}

}

/* Now, wait for the results to come back in */

while (count($sockets)) {

$read = $write = $sockets;

/* This is the magic function - explained below */

$n = stream_select($read, $write, $e = null, $timeout);

if ($n > 0) {

/* readable sockets either have data for us, or are failed

* connection attempts */

foreach ($read as $r) {

$id = array_search($r, $sockets);

$data = fread($r, 8192);

if (strlen($data) == 0) {

if ($status[$id] == "in progress") {

$status[$id] = "failed to connect";

}

fclose($r);

unset($sockets[$id]);

} else {

$status[$id] .= $data;

}

}

/* writeable sockets can accept an HTTP request */

foreach ($write as $w) {

$id = array_search($w, $sockets);

fwrite($w, "HEAD / HTTP/1.0rnHost: "

. $hosts[$id] . "rnrn");

$status[$id] = "waiting for response";

}

} else {

/* timed out waiting; assume that all hosts associated

* with $sockets are faulty */

foreach ($sockets as $id => $s) {

$status[$id] = "timed out " . $status[$id];

}

break;

}

}

foreach ($hosts as $id => $host) {

echo "Host: $hostn";

echo "Status: " . $status[$id] . "nn";

}

?>

我們用stream_select()等待sockets打開的連接事件。stream_select()調用系統(tǒng)的select(2)函數來工作:前面三個參數是你要使用的streams的數組;你可以對其讀取,寫入和獲取異常(分別針對三個參數)。stream_select()可以通過設置$timeout(秒)參數來等待事件發(fā)生-事件發(fā)生時,相應的sockets數據將寫入你傳入的參數。

下面是PHP4.1.0之后版本的實現,如果你已經在編譯PHP時包含了sockets(ext/sockets)支持,你可以使用根上面類似的代碼,只是需要將上面的streams/filesystem函數的功能用ext/sockets函數實現。主要的不同在于我們用下面的函數代替stream_socket_client()來建立連接:

代碼如下

// This value is correct for Linux, other systems have other values

define("EINPROGRESS", 115);

function non_blocking_connect($host, $port, &$errno, &$errstr, $timeout) {

$ip = gethostbyname($host);

$s = socket_create(AF_INET, SOCK_STREAM, 0);

if (socket_set_nonblock($s)) {

$r = @socket_connect($s, $ip, $port);

if ($r || socket_last_error() == EINPROGRESS) {

$errno = EINPROGRESS;

return $s;

}

}

$errno = socket_last_error($s);

$errstr = socket_strerror($errno);

socket_close($s);

return false;

}

?>

現在用socket_select()替換掉stream_select(),用socket_read()替換掉fread(),用socket_write()替換掉fwrite(),用socket_close()替換掉fclose()就可以執(zhí)行腳本了!

PHP5的先進之處在于,你可以用stream_select()處理幾乎所有的stream-例如你可以通過include STDIN用它接收鍵盤輸入并保存進數組,你還可以接收通過proc_open()打開的管道中的數據。

下面來分享一個PHP多線程類

代碼如下

* @title: PHP多線程類(Thread)

* @version: 1.0

* @author: phper.org.cn < web@phper.org.cn >

* @published: 2010-11-2

*

* PHP多線程應用示例:

* require_once "thread.class.php";

* $thread = new thread();

* $thread->addthread("action_log","a");

* $thread->addthread("action_log","b");

* $thread->addthread("action_log","c");

* $thread->runthread();

*

* function action_log($info) {

* $log = "log/" . microtime() . ".log";

* $txt = $info . "rnrn" . "Set in " . Date("h:i:s", time()) . (double)microtime() . "rn";

* $fp = fopen($log, "w");

* fwrite($fp, $txt);

* fclose($fp);

* }

*/

class thread {

var $hooks = array();

var $args = array();

function thread() {

}

function addthread($func)

{

$args = array_slice(func_get_args(), 1);

$this->hooks[] = $func;

$this->args[] = $args;

return true;

}

function runthread()

{

if(isset($_GET["flag"]))

{

$flag = intval($_GET["flag"]);

}

if($flag || $flag === 0)

{

call_user_func_array($this->hooks[$flag], $this->args[$flag]);

}

else

{

for($i = 0, $size = count($this->hooks); $i < $size; $i++)

{

$fp=fsockopen($_SERVER["HTTP_HOST"],$_SERVER["SERVER_PORT"]);

if($fp)

{

$out = "GET {$_SERVER["PHP_SELF"]}?flag=$i HTTP/1.1rn";

$out .= "Host: {$_SERVER["HTTP_HOST"]}rn";

$out .= "Connection: Closernrn";

fputs($fp,$out);

fclose($fp);

}

}

}

}

}

詞條內容僅供參考,如果您需要解決具體問題
(尤其在法律、醫(yī)學等領域),建議您咨詢相關領域專業(yè)人士。

標簽

多線程

推薦詞條

主站蜘蛛池模板: 午夜一级在线 | 久久九九精品国产av片国产 | 日韩黄色电影免费在线 | 99久久婷婷国产综合精品交换 | 国产精品无码无卡免费观 | 老熟女高潮一区二区三区 | 绯色国产av无码一区二区 | 波多野结衣高清无码视频 | 国产成人精品亚洲2020 | 成人欧美一区在线视 | 岛国精品一区免费视频在线观看 | 人妻中文系列无码专区 | 午夜网未来影院 | 国产欧美一区二区三区免费 | 亚洲国产欧美日韩另类 | 亚洲精品制服丝袜二区 | 久久久久精品久久久久影院 | 99久在线国内在线播放免费观看 | 91国偷自产中文字幕婷婷 | 日韩一区二区三区免费体验 | 亚洲国产综合久久久无码色伦 | 精品国产日韩亚洲一区 | 国产精品部在线观看 | 亚洲日韩精品欧美一区二区 | 精品日本三级乱伦 | 吉泽明步高清无码中文 | 麻豆黑色丝袜j | 久久精品二三区 | 中文无码乱人伦中文视频播放 | 国产成人精品免费视频软件 | 无码专区一ⅴa亚洲v专区在线 | 国产精品久久精品成人网站 | 99久久永久免费热播 | 久久午夜无码影视 | 亚洲国产日韩欧美在线 | a一片女人一区二区三区 | 苍井空50分钟无码种子 | 国产成人无码午夜视频在线播放 | 2024国产在线a在线不卡 | 97国语精品自产拍在线观看 | 亚洲.午夜无码在线视频 |