A. php線程安全與非線程安全的區別:如何選擇用哪一個
首先,linux下的PHP,沒有線程安全版和非線程安全版之分。從2000年10月20日發布的第一個Windows版的PHP3.0.17開始的都是線程安全的版本,直至5.2.1版本開始有Thread Safe(TS,線程安全)和None Thread Safe(NTS,非線程安全)之分。
因為,Linux/Unix系統採用的是多進程的工作方式,而Windows系統採用多線程的工作方式。即:Linux系統的任務調度基本單位是進程,Windows系統的任務調度基本單位是線程(本觀點來自自學與總結,不能保證百分之百正確)。
所以,在Windows系統的IIS下以CGI方式運行PHP會非常慢,這是由於CGI模式是建立在多進程的基礎之上的,而非多線程,且CGI模式對於每個HTTP請求都需要重新載入和卸載整個PHP環境,其消耗是巨大的。
於是,一般我們會把PHP配置成以ISAPI的方式來運行,ISAPI是多線程的方式,這樣就快多了。但存在一個問題,很多常用的PHP擴展是以 Linux/Unix的多進程思想來開發的,這些擴展在ISAPI的方式運行時就會出錯搞垮IIS。
為了兼顧IIS下PHP的效率和安全,微軟給出了FastCGI的解決方案。FastCGI可以讓PHP的進程重復利用,而不是每一個新的請求就重開一個進程。同時FastCGI也可以允許幾個進程同時執行。這樣既解決了CGI進程模式消耗太大的問題,又利用上了CGI進程模式不存在線程安全問題的優勢。
因此,如果是使用ISAPI的方式來運行PHP就必須用Thread Safe(TS,線程安全)的版本;而用FastCGI模式運行PHP的話就沒有必要用線程安全檢查了,用None Thread Safe(NTS,非線程安全)的版本能夠更好的提高效率。
名詞解析:
IIS:Internet Information Services (互聯網信息服務),是由微軟公司提供的基於運行Microsoft Windows的互聯網基本服務
CGI:Common Gateway Interface (通用網關介面),是外部應用程序(CGI程序)與Web伺服器之間的介面標准
ISAPI:Internet Server Application Programming Interface (互聯網應用程序介面),是為Microsoft所提的Internet server的API
FastCGI:CGI存在收到每個請求時都開辟一個進程等不足,FastCGI可以理解為是征對CGI的改進版
B. PHP支持多線程嗎
PHP語言本身是不支持多線程的。網上關於PHP模擬多線程的方法,都是利用了LINUX和APACHE等本身所具有的多線程能力。既然是模擬的,就不是真正的多線程,其實只是多進程。
1. 利用LINUX操作系統
<?php
for ($i=0;$i<10;$i++) {
echo $i;
sleep(5);
}
?>
上面存成test.php, 然後寫一段SHELL代碼
#!/bin/bash
for i in 1 2 3 4 5 6 7 8 9 10
do
php -q test.php &
done
2. 利用fork子進程(其實同樣是利用LINUX操作系統)
<?php
declare(ticks=1);
$bWaitFlag = FALSE; /// 是否等待進程結束
$intNum = 10; /// 進程總數
$pids = array(); /// 進程PID數組
echo ("Startn");
for($i = 0; $i < $intNum; $i++) {
$pids[$i] = pcntl_fork();/// 產生子進程,而且從當前行之下開試運行代碼,而且不繼承父進程的數據信息
if(!$pids[$i]) {
// 子進程進程代碼段_Start
$str="";
sleep(5+$i);
for ($j=0;$j<$i;$j++) {$str.="*";}
echo "$i -> " . time() . " $str n";
exit();
// 子進程進程代碼段_End
}
}
if ($bWaitFlag)
{
for($i = 0; $i < $intNum; $i++) {
pcntl_waitpid($pids[$i], $status, WUNTRACED);
echo "wait $i -> " . time() . "n";
}
}
echo ("Endn");
?>
3. 利用WEB SERVER, PHP不支持多線程, APACHE可是支持的, 呵呵.
假設我們現在運行的是a.php這個文檔. 但是我在程式中又請求WEB伺服器運行另一個b.php
那麼這兩個文檔將是同時執行的.
<?php
function runThread()
{
$fp = fsockopen('localhost', 80, $errno, $errmsg);
fputs($fp, "GET /a.php?act=brnrn");
fclose($fp);
}
function a()
{
$fp = fopen('result_a.log', 'w');
fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn");
fclose($fp);
}
function b()
{
$fp = fopen('result_b.log', 'w');
fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn");
fclose($fp);
}
if(!isset($_GET['act'])) $_GET['act'] = 'a';
if($_GET['act'] == 'a')
{
runThread();
a();
}
else if($_GET['act'] == 'b') b();
?>
也可以把需要多線程處理的部分交給java去處理,然後在PHP里調用。
<?php
system('java multiThread.java');
?>
C. php 線程
以下都是轉載, 簡單說下, php是不支持多線程的。。。。
PHP語言本身是不支持多線程的. 總結了一下網上關於PHP模擬多線程的方法, 總的來說, 都是利用了PHP的好夥伴們本身所具有的多線程能力. PHP的好夥伴指的就是LINUX和APACHE啦, LAMP嘛.
另外, 既然是模擬的, 就不是真正的多線程. 其實只是多進程. 進程和線程是兩個不同的概念. 好了, 以下方法都是從網上找來的.
1. 利用LINUX操作系統
<?php
for ($i=0;$i<10;$i++) {
echo $i;
sleep(5);
}
?>
上面存成test.php, 然後寫一段SHELL代碼
#!/bin/bash
for i in 1 2 3 4 5 6 7 8 9 10
do
php -q test.php &
done
2. 利用fork子進程(其實同樣是利用LINUX操作系統)
<?php
declare(ticks=1);
$bWaitFlag = FALSE; /// 是否等待進程結束
$intNum = 10; /// 進程總數
$pids = array(); /// 進程PID數組
echo ("Startn");
for($i = 0; $i < $intNum; $i++) {
$pids[$i] = pcntl_fork();/// 產生子進程,而且從當前行之下開試運行代碼,而且不繼承父進程的數據信息
if(!$pids[$i]) {
// 子進程進程代碼段_Start
$str="";
sleep(5+$i);
for ($j=0;$j<$i;$j++) {$str.="*";}
echo "$i -> " . time() . " $str n";
exit();
// 子進程進程代碼段_End
}
}
if ($bWaitFlag)
{
for($i = 0; $i < $intNum; $i++) {
pcntl_waitpid($pids[$i], $status, WUNTRACED);
echo "wait $i -> " . time() . "n";
}
}
echo ("Endn");
?>
3. 利用WEB SERVER, PHP不支持多線程, APACHE可是支持的, 呵呵.
假設我們現在運行的是a.php這個文檔. 但是我在程式中又請求WEB伺服器運行另一個b.php
那麼這兩個文檔將是同時執行的.
<?php
function runThread()
{
$fp = fsockopen('localhost', 80, $errno, $errmsg);
fputs($fp, "GET /a.php?act=brnrn");
fclose($fp);
}
function a()
{
$fp = fopen('result_a.log', 'w');
fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn");
fclose($fp);
}
function b()
{
$fp = fopen('result_b.log', 'w');
fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn");
fclose($fp);
}
if(!isset($_GET['act'])) $_GET['act'] = 'a';
if($_GET['act'] == 'a')
{
runThread();
a();
}
else if($_GET['act'] == 'b') b();
?>
當然啦,也可以把需要多線程處理的部分交給JAVA去處理, 然後在PHP里調用, 哈哈.
<?php
system('java multiThread.java');
?>
D. Nginx下php裝什麼版本及PHP的線程安全與非線程安全版本的區別
一般我們會把PHP配置成以ISAPI的方式來運行,ISAPI是多線程的方式,這樣就快多了。但存在一個問題,很多常用的PHP擴展是以 Linux/Unix的多進程思想來開發的,這些擴展在ISAPI的方式運行時就會出錯搞垮IIS。因此在IIS下CGI模式才是PHP運行的最安全方 式,但CGI模式對於每個HTTP請求都需要重新載入和卸載整個PHP環境,其消耗是巨大的。
E. php是單線程非阻塞嗎
PHP支持多線程,也可以阻塞,根據需要選擇編寫不同的代碼。
F. 怎麼在linux運行php文件
1、打開我們的linux命令行,准備好。
2、找到php的安裝目錄,主要是找到linux環境下,php可執行文件的目錄。如圖所示。筆者的目錄為/opt/lampp/bin/php,將此目錄記下,備用。
3、找到要運行的php文件所在的目錄,隨便寫點php代碼就可以,在此筆者已經准備好。/opt/lampp/htdocs/wechat/xjtest-web_browser/pcntl_test.php,將此目錄記下,接下來就要正式開始運行了。
4、打開剛剛第一步打開的linux命令行,輸入/opt/lampp/bin/php /opt/lampp/htdocs/wechat/xjtest-web_browser/pcntl_test.php(即依次輸入剛剛的兩個目錄)注意兩個目錄中間有空格。
5、按下回車,可以看到,php文件已經正確執行了。
G. php多線程
以下都是轉載, 簡單說下, php是不支持多線程的。。。。
PHP語言本身是不支持多線程的. 總結了一下網上關於PHP模擬多線程的方法, 總的來說, 都是利用了PHP的好夥伴們本身所具有的多線程能力. PHP的好夥伴指的就是LINUX和APACHE啦, LAMP嘛.
另外, 既然是模擬的, 就不是真正的多線程. 其實只是多進程. 進程和線程是兩個不同的概念. 好了, 以下方法都是從網上找來的.
1. 利用LINUX操作系統
<?php
for ($i=0;$i<10;$i++) {
echo $i;
sleep(5);
}
?>
上面存成test.php, 然後寫一段SHELL代碼
#!/bin/bash
for i in 1 2 3 4 5 6 7 8 9 10
do
php -q test.php &
done
2. 利用fork子進程(其實同樣是利用LINUX操作系統)
<?php
declare(ticks=1);
$bWaitFlag = FALSE; /// 是否等待進程結束
$intNum = 10; /// 進程總數
$pids = array(); /// 進程PID數組
echo ("Startn");
for($i = 0; $i < $intNum; $i++) {
$pids[$i] = pcntl_fork();/// 產生子進程,而且從當前行之下開試運行代碼,而且不繼承父進程的數據信息
if(!$pids[$i]) {
// 子進程進程代碼段_Start
$str="";
sleep(5+$i);
for ($j=0;$j<$i;$j++) {$str.="*";}
echo "$i -> " . time() . " $str n";
exit();
// 子進程進程代碼段_End
}
}
if ($bWaitFlag)
{
for($i = 0; $i < $intNum; $i++) {
pcntl_waitpid($pids[$i], $status, WUNTRACED);
echo "wait $i -> " . time() . "n";
}
}
echo ("Endn");
?>
3. 利用WEB SERVER, PHP不支持多線程, APACHE可是支持的, 呵呵.
假設我們現在運行的是a.php這個文檔. 但是我在程式中又請求WEB伺服器運行另一個b.php
那麼這兩個文檔將是同時執行的.
<?php
function runThread()
{
$fp = fsockopen('localhost', 80, $errno, $errmsg);
fputs($fp, "GET /a.php?act=brnrn");
fclose($fp);
}
function a()
{
$fp = fopen('result_a.log', 'w');
fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn");
fclose($fp);
}
function b()
{
$fp = fopen('result_b.log', 'w');
fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn");
fclose($fp);
}
if(!isset($_GET['act'])) $_GET['act'] = 'a';
if($_GET['act'] == 'a')
{
runThread();
a();
}
else if($_GET['act'] == 'b') b();
?>
當然啦,也可以把需要多線程處理的部分交給JAVA去處理, 然後在PHP里調用, 哈哈.
<?php
system('java multiThread.java');
?>
H. linux php怎麼添加多線程
開始用php寫後台服務一段時間了.也是在這樣的驅動下,不斷的學習php語法,體驗這一原來一直以為神秘且敬而遠之的神奇語言的魅力.最初看php多線程的資料是為了提高程序的處理能力,充分發揮linux多任務的優勢.不曾想多線程沒用成反到是帶來了一系列的意外收獲.讓之後的許多問題迎刃而解,不敢獨享特一一道來.
本文所講的東西是源自php的pcntl_fork函數.因為這個函數依賴操作系統fork的實現,所以本文所講的東西只適用於linux/unix.ok,那麼先看看這個函數的用法吧.php手冊上是這么說的:
<?php
$pid = pcntl_fork();
if ($pid == -1) {
die('could not fork');
} else if ($pid) {
// we are the parent
pcntl_wait($status); //Protect against Zombie children
} else {
// we are the chil
I. php如何來多線程運行多個腳步
測試多進程PHP調用執行shell程序性能。。
寫php代碼實現多進程調用肯定比較難,因為在PHP沒有統一的進程管理庫。win和linux不一樣,也曲折。
僅僅為了測試。把PHP單次exec調用py的代碼放在活動的伺服器(比如apache或iis或nginx任何)上。然後用apache的ab工具測試一下壓力就知道性能了。
J. 討論php程序執行是線程還是進程
進程
進程是什麼?進程是正在執行的程序;進程是正在計算機上執行的程序實例;進程是能分配給處理器並由處理器執行的實體。 進程一般會包括指令集和系統資源集,這里的指令集是指程序代碼,這里的系統資源集是指I/O、CPU、內存等。 綜合起來,我們也可以理解進程是具有一定獨立功能的程序在關於某個數據集合上的一次運行活動, 進程是系統進行資源分配和調度的一個獨立單位。
在進程執行時,進程都可以被唯一的表示,由以下一些元素組成:
進程描述符:進程的唯一標識符,用來和其它進程區分。在Linux中叫進程ID,在系統調用fork期間生成,只是我們通過getpid返回的不是其pid欄位,而是其線程組號tgid。
進程狀態:我們常說的掛起、運行等狀態,其表示的是當前的狀態。
優先順序:進程間的執行調度相關,相對於其它進程而言。
程序計數器:程序中即將被執行的下一條指令的地址,該地址是內核術中或用戶內存空間中的內存地址。
內存指針:包括程序代碼和進程相關數據的指針,還有和其它進程共享內存塊的指針。
上下文數據:進程執行時處理器的寄存器的數據。
I/O狀態信息:包括顯式的I/O請求、分配給進程的I/O設備等
記賬信息:可能包括處理器時間總和、使用的時鍾數總和、時間限制等
以上的這些元素都會放在一個叫做進程式控制制塊的數據結構中。進程式控制制塊是操作系統能夠支持多進程和提供多處理的結構。 當操作系統做進程切換時,它會執行兩步操作,一是中斷當前處理器中的進程,二是執行下一個進程。 不管是中斷還是執行,進程式控制制塊中的程序計數器、上下文數據和進程狀態都會發生變化。 當進程中斷時,操作系統會把程序計數器和處理器寄存器(對應進程式控制制塊中的上下文數據)保存到進程式控制制塊中的相應位置, 進程狀態也會有所變化,可能進入阻塞狀態,也有可能進入就緒態。 當執行下一個進程時,操作系統按規則將下一個進程設置為運行態,並載入即將要執行進程的程序上下文數據和程序計數器等。
線程
進程有兩個特性部分:資源所有權和調度執行。 資源所有權是指進程包括了進程運行所需要的內存空間、I/O等資源。 調度執行是指進程執行過程中間的執行路徑,或者說程序的指令執行流。 這兩個特性部分是可以分開的,分開後,擁有資料所有權的通常稱為進程,擁有執行代碼的可分派部分的被稱之為線程或輕量級進程。
線程有「執行的線索」的意思在裡面,而進程在多線程環境中被定義為資源所有者,其還是會存儲進程的進程式控制制塊。 線程的結構與進程不同,每個線程包括:
線程狀態: 線程當前的狀態。
一個執行棧
私有的數據區: 用於每個線程局部變數的靜態存儲空間
寄存器集: 存儲處理器的一些狀態
每個進程都有一個進程式控制制塊和用戶地址空間,每個線程都有一個獨立的棧和獨立的控制塊,都有自己一個獨立執行上下文。