The following is about PHP multi-threading problems, PHP's pthreads extension and curl_multi_init function. When you encounter such problems and cannot solve them, take a look at how others solved them.
Installing php real multi-thread extension pthreads tutorial under windows
Extension address: http://docs.php.net/manual/zh/book .pthreads.php
Notes
php5.3 or above, and it is a thread-safe version. The compilers used by apache and php must be consistent.
Check Thread Safety through phpinfo() if it is enabled, it is a thread-safe version.
You can know the compiler used by viewing the Compiler item through phpinfo(). Mine is: MSVC9 (Visual C++ 2008).
Use environment
32-bit windows xp sp3, wampserver2.2d (php5.3.10-vc9 + apache2.2.21-vc9).
1. Download pthreads extension
Download address: http://windows.php.net/downloads/pecl/releases/pthreads
According to my environment, I downloaded pthreads-2.0.8-5.3- ts-vc9-x86.
2.0.8 represents the version of pthreads.
5.3 represents the php version.
ts means that php requires a thread-safe version.
vc9 means that php needs to be compiled with Visual C++ 2008 compiler.
x86 means 32-bit
2. Install pthreads extension
Copy php_pthreads.dll to the directory bin\php\ext\. (My path is D:\wamp\bin\php\php5.3.10\ext)
Copy pthreadVC2.dll to the directory bin\php\. (My path is D:\wamp\bin\php\php5.3.10)
Copy pthreadVC2.dll to the directory C:\windows\system32.
Open the php configuration file php.ini. Add extension=php_pthreads.dll
prompt at the end! Windows systems need to add the path of pthreadVC2.dll to the PATH environment variable. My Computer--->right mouse button--->Properties--->Advanced--->Environment Variables--->System Variables--->Find the path named Path---> ;Edit--->Add the full path of pthreadVC2.dll at the end of the variable value (mine is C:\WINDOWS\system32\pthreadVC2.dll).
3. Test pthreads extension
class AsyncOperation extends \Thread { public function __construct($arg){ $this->arg = $arg; } public function run(){ if($this->arg){ printf("Hello %s\n", $this->arg); } } } $thread = new AsyncOperation("World"); if($thread->start()) $thread->join(); ?>
Hello World appears when running the above code, indicating that the pthreads extension is installed successfully!
Attached is a simple example of Thinkphp3.2.2
<?php namespace Home\Controller; class test extends \Thread { public $url; public $result; public function __construct($url) { $this->url = $url; } public function run() { if ($this->url) { $this->result = model_http_curl_get($this->url); } } } function model_http_curl_get($url) { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_TIMEOUT, 5); curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2)'); $result = curl_exec($curl); curl_close($curl); return $result; } for ($i = 0; $i < 10; $i++) { $urls[] = 'http://www.baidu.com/s?wd='. rand(10000, 20000); } /* 多线程速度测试 */ $t = microtime(true); foreach ($urls as $key=>$url) { $workers[$key] = new test($url); $workers[$key]->start(); } foreach ($workers as $key=>$worker) { while($workers[$key]->isRunning()) { usleep(100); } if ($workers[$key]->join()) { dump($workers[$key]->result); } } $e = microtime(true); echo "多线程耗时:".($e-$t)."秒<br>"; /* 单线程速度测试 */ $t = microtime(true); foreach ($urls as $key=>$url) { dump(model_http_curl_get($url)); } $e = microtime(true); echo "For循环耗时:".($e-$t)."秒<br>";
The test results are as follows:
Multi-threading time consumption: 2.8371710777282714844 seconds
For loop time consumption: 10.941586017608642578 seconds
curl_multi_init()
<?php echo date("Y-m-d H:m:s",time()); echo " ";echo floor(microtime()*1000); echo "<br>";$mtime = explode(" ", microtime());$mtime = $mtime[1].($mtime[0] * 1000); $mtime2 = explode(".", $mtime); $mtime = $mtime2[0]; echo $mtime;echo "<br>"; $urls=array('http://www.a.com', 'http://www.b.com', 'http://www.c.com', 'http://www.d.com','http://www.e.com'); print_r(async_get_url($urls)); //[0]=>example1,[1]=>example2 echo "<br>"; echo date("Y-m-d H:m:s",time()); echo " "; echo floor(microtime()*1000); echo "<br>"; $mtime_ = explode(" ", microtime()); $mtime_ = $mtime_[1].($mtime_[0] * 1000); $mtime2_ = explode(".", $mtime_);$mtime_ = $mtime2_[0]; echo $mtime_; echo "<br>"; echo $mtime_ - $mtime; function async_get_url($url_array, $wait_usec = 0) { if (!is_array($url_array)) return false; $wait_usec = intval($wait_usec); $data = array(); $handle = array(); $running = 0; $mh = curl_multi_init(); // multi curl handler$i = 0; foreach($url_array as $url) { $ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return don't printcurl_setopt($ch, CURLOPT_TIMEOUT, 30); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 302 redirectcurl_setopt($ch, CURLOPT_MAXREDIRS, 7); curl_multi_add_handle($mh, $ch); // 把 curl resource 放进 multi curl handler 里 $handle[$i++] = $ch;} /* 执行 */ do { curl_multi_exec($mh, $running); if ($wait_usec > 0) /* 每个 connect 要间隔多久 */ usleep($wait_usec); // 250000 = 0.25 sec} while ($running > 0);/* 读取资料 */ foreach($handle as $i => $ch) {$content = curl_multi_getcontent($ch); $data[$i] = (curl_errno($ch) == 0) ? $content : false;} /* 移除 handle*/ foreach($handle as $ch) { curl_multi_remove_handle($mh, $ch); } curl_multi_close($mh); return $data;} ?>
About curl_multi_init()
Generally speaking, when you think of using curl_multi_init(), the purpose is It is necessary to request multiple URLs at the same time instead of requesting them one by one, otherwise curl_init() will be needed.
However, when using curl_multi, you may encounter phenomena such as excessive CPU consumption and suspended animation of web pages. You can take a look at how to solve the problem of suspended animation caused by curl_multi.
Summary of steps for using curl_multi As follows:
Step 1: Call curl_multi_init
Step 2: Call curl_multi_add_handle in a loop
It should be noted in this step that the second parameter of curl_multi_add_handle is the subhandle from curl_init.
Step 3: Continuously call curl_multi_exec
Step 4: Cyclically call curl_multi_getcontent to obtain the results as needed
Step 5: Call curl_multi_remove_handle, and call curl_close for each word handle
Step 6: Call curl_multi_close
Explanation of the functions of each function:
curl_multi_init()
Initialize a curl batch handle resource.
curl_multi_add_handle()
Add separate curl handle resources to the curl batch session. The curl_multi_add_handle() function has two parameters. The first parameter represents a curl batch handle resource, and the second parameter represents a separate curl handle resource.
curl_multi_exec()
Parse a curl batch handle. The curl_multi_exec() function has two parameters. The first parameter represents a batch handle resource, and the second parameter is a parameter that refers to a value. Indicates the number of individual curl handle resources remaining that need to be processed.
curl_multi_remove_handle()
Remove a handle resource in the curl batch handle resource. The curl_multi_remove_handle() function has two parameters. The first parameter represents a curl batch handle resource, and the second parameter The parameter represents a separate curl handle resource.
curl_multi_close()
Close a batch handle resource.
curl_multi_getcontent()
When CURLOPT_RETURNTRANSFER is set, return the text stream of the obtained output.
curl_multi_info_read()
Get the relevant transmission information of the currently parsed curl.
This article is shared about PHP multi-threading issues. I hope it will be helpful to everyone. If you have any questions, you can leave your comments or suggestions. In the future, the editor will share a lot of articles about this kind of articles, so please pay more attention to them.
The above is the detailed content of Regarding PHP multi-threading processing issues. For more information, please follow other related articles on the PHP Chinese website!