class Request extends Thread {
public $url;
public $response;
public function __construct($url) {
$this->url = $url;
}
public function run() {
$this->response = file_get_contents($this->url);
}
}
线程(thread) 是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务.
使用多线程主要是因为它在执行效率上有很大优势。由于线程是操作系统能够进行调度的最小单位:
- 一个多线程程序比单线程程序被操作系统调度的概率更大,所以多线程程序一般会比单线程程序更高效;
- 多线程程序的多个线程可以在多核 CPU 的多个核心同时运行,可以将完全发挥机器多核的优势;
同时对比多进程程序,多线程有以下特点:
- 线程的创建和切换的系统开销都比进程要小,所以一定程度上会比多进程更高效;
- 线程天生的共享内存空间,线程间的通信更简单,避免了进程IPC引入新的复杂度。
多线程是让程序变得不安分的一个因素,在使用多线程之前,首先要考虑线程安全问题:
线程安全:线程安全是编程中的术语,指某个函数、函数库在多线程环境中被调用时,能够正确地处理多个线程之间的共享变量,使程序功能正确完成。
在传统多线程中,由于多个线程共享变量,所以可能会导致出现如下问题:
1.存在一个全局数组$arr = array('a');;
2.A 线程获取数组长度为1;
3.B 线程获取数组长度为1;
4.A 线程 pop 出数组元素 $a = array_pop($arr); $a = 'a';;
5.B 线程也 pop 数组元素 $b = array_pop($arr); $a = null;;
6.此时 B 线程内就出现了灵异事件,明明数组长度大于0,或没有 pop 出东西;
将同步的请求拆分为多个线程异步调用,以提升程序的运行效率。
$chG = new Request("www.google.com");
$chB = new Request("www.baidu.com");
$chG ->start();
$chB ->start();
$chG->join();
$chB->join();
$gl = $chG->response;
$bd = $chB->response;
此时主线程相当于旗舰,而各子线程相当于巡航舰,旗舰到达某地后不必要一直等待巡航舰也归来,等待一段时间后离开即可,从而避免巡航舰意外时旗舰白白空等。
$chG = new Request("www.google.com");
$chB = new Request("www.baidu.com");
$chG->start();
$chB->start();
$chB->join();
// 此处不对chG执行join方法
sleep(1); // sleep一个能接受的超时时间
$gl = $chG->response;
$bd = $chB->response;
$bd->kill();
if (!$gl) {
$gl = ""; // 处理异常,或在线程类内给$gl一个默认值
}
有关php多线程编程异步处理的问题请移步学习网了解