当前位置 »威客网 » 新闻中心 »老鸟带你飞,多线程program-php如何实现

老鸟带你飞,多线程program-php如何实现

2017年12月5日来源:bd5029685ef27cfa2be3e91ccdf9a34f威客网小分类:[$-小分类-$]

新闻摘要:线程安全的PHP实现机制主要是将全局变量和静态变量、全局变量和静态变量分离到每个线程以复制a,每个线程使用的是备份的主线程,避免了变量冲突,没有线程安全问题。
前言

帮助同事检查一个问题有一天,我是第一个到达PHP多线程,一般认为PHP是单线程模型,不适合多线程,花一些时间翻几多线程程序源代码,还发现了一个PHP多线程有可取之处,使用,非常适合来解决一些问题。

已经发现了一些文章,可以看到PHP多线程TSRM机制的实现,细节可以在以下引用中找到。
本文介绍了多线程的优点和应用场景,提出了一种新的方法,并利用PHP代码实现了多线程的常见用法。

线程是操作系统能够执行操作的最小单元。
它包括在过程中,是过程中的实际操作单位。
线程指的是一个过程中的一个顺序控制流,它可以与多个线程并发,每个线程并行执行不同的任务。
使用多线程的主要原因是它在执行效率方面有很大的优势。
因为线程是操作系统可以调度的最小单元:

多线程程序比单线程程序更容易被调度,因此多线程程序通常比单线程程序更有效。
多线程程序的多线程可以在多核cpu的多个核心上运行,这可以充分发挥多核机器的优势;
同时,对多进程程序进行了比较,多线程具有以下特点:

线程创建和切换的系统开销小于进程,因此比多进程更有效。
线程本质上是共享内存空间,线程之间的通信更简单,避免了进程IPC的新复杂性。
适用的场景

多线程优化有很多,但是没有使用多线程的大脑,不能提高执行效率,因为线程创建和销毁、上下文切换、线程同步等。
如:

SumSmall是一个从1到50,000的函数。



在上述的主线程三sumSmall分别和三个线程执行sumSmall,然后同步到一个线程的时候,我们会发现,而不是只有主线程的执行时间较短,三个线程创建、切换、线程同步的时间远远大于异步执行时间保存。

函数sumLarge从1到5000000,同样的线程可以执行三次和三个线程执行时间:



这一次,多线程终于有了一个有效的优势。

是否使用多线程也取决于具体的需求,通常考虑以下两种情况:

I/ O阻塞导致操作系统调度阻塞当前任务的任务,所以在代码中I / O的情况下,当您使用多个线程时,可以并行化代码。
例如,多次读取整个文件或请求多个网络资源。
多线程可以充分利用CPU,因此,当您有多个大量的代码时,可以使用多个线程使它们并行执行,例如前一篇文章中的示例。
在PHP中多线程
默认的PHP不支持多线程,使用多线程需要安装pthread扩展,并且安装pthread扩展,必须使用-启用重新编译PHP -维护者- ZTS参数,这个参数在指定编译PHP线程安全的方式时使用。

线程安全

多线程是导致程序不稳定的一个因素,在使用多线程之前考虑线程安全性是很重要的:

线程安全:线程安全是编程中使用的术语,在多线程环境中引用函数,函数库被调用,正确处理多个线程间的共享变量,使程序正常运行。
在传统的多线程中,由于多个线程共享变量,可能导致以下问题:

有一个全局数组$ arr = array(a);
线程的数组长度为1;
B线程获取数组1的长度;
一个线程会弹出数组元素$ A = array_pop($arr);
美元= a ;;
B线程也会弹出数组元素$ B = array_pop($arr);
美元=零;;
在这种情况下,B线程中存在一个大于0的通灵事件,或者没有弹出。
PHP实现

线程安全的PHP实现机制主要是将全局变量和静态变量、全局变量和静态变量分离到每个线程以复制a,每个线程使用的是备份的主线程,避免了变量冲突,没有线程安全问题。

PHP用于多线程打包,以确保线程安全,程序员不必考虑全局变量和各种锁,以避免冲突、会话、读写,但也减少了出错的几率,编写更安全的代码。

但结果是,一旦子线程开始运行,主线程就不能再次为线程调整操作细节,线程在全局变量消息传递功能之间部分丢失。

在打开线程安全选项PHP之后,使用TSRM机制分配和使用变量也会有额外的损失,因此不需要多线程环境,PHP使用PHP ZTS版本(不是线程安全的)。

类和方法

PHP包线程变成了一个线程类,通过实例化一个线程对象来创建线程,这是类封装的结果,变量的使用只能通过构造函数和线程操作结果引入并通过类变量来实现。

以下是一些常见的线程方法:

Run():这个方法是一个抽象的方法,每个线程都实现这个方法,这个方法中的代码在线程开始运行后自动执行;
Start():在主线程中调用此方法以开始运行线程;
Join():每个线程都与主线程异步执行,调用该方法等待线程执行;
Kill():强制线程结束;
IsRunning():返回线程的运行状态,当线程执行run()方法的代码时,该线程返回true;
由于线程安全的实现,PHP多线程开始运行,不能再通过共享内存空间通信,线程也不能在线程重用之间进行通信,所以我认为PHP“线程池”是没有意义的。
扩展中的内置池类是一个用于多线程分配管理的类,不再被覆盖。

示例代码
以下是一个请求接口的线程类。
接下来,编写两个多线程应用程序示例:

类请求扩展线程{
公共url美元;
公共美元反应;
公共功能__construct($ url){
$this - > url = $url;
}
公共函数运行(){
$this - > response = file_get_contents($ this - > url);
}
}
异步请求

将同步请求拆分为多个线程异步调用,以提高程序的运行效率。

$chG =新请求(www.google.com);
$chB = new Request(" www.baidu.com ");
$chG - >开始();
$chB - >开始();
$chG - >连接();
$chB - >连接();

$gl = $chG - >响应;
$bd = $chB - >响应;
超时控制

不小心发现公司的网站在网页上有一块内容,不知道具体的实现,但它给了我使用多线程的灵感:使用线程异步实现快速失败,控制超时。

当我们使用curl来请求一个地址时,我们可以设置curl的连接超时时间,使用CURLOPT_CONNECTTIMEOUT / CURLOPT_TIMEOUT参数读取数据超时,但是总的超时时间没有得到很好的控制。
而数据库查询的超时时间没有设置(bird的博客:为MySQL设置查询超时)。

然后我们可以使用多个线程来实现这一点:在执行线程类的start()方法之后,如果没有调用join()方法,线程就处于异步状态,而不是阻塞主线程的执行。

作为旗舰的主线,每一个孩子的线程都等于游船,在抵达游船后的不必要等待的旗舰也回来了,在等待一段时间后离开,以避免一艘游船意外的旗舰在徒劳的等待。
代码:

$chG =新请求(www.google.com);
$chB = new Request(" www.baidu.com ");
$chG - >开始();
$chB - >开始();
$chB - >连接();
/ /没有chG的连接方法

睡眠(1);
/ /睡眠是一个可以接受的超时
$gl = $chG - >响应;
$bd = $chB - >响应;
$bd - > kill();
如果(!
$ { gl)
gl美元= " ";
/ /处理异常,或者在线程类中使用$ gl的默认值
}
总结

PHP是多线程的(通用),这使得人们使用线程非常不流行。
虽然它是安全的,但它使PHP保持简单易用,但它没有完全多线程的能力。
但是每种语言都有它自己的特点和优先级,而且不需要苛刻。

最近,我学习了操作系统和Linux内核,极大地提高了程序的认知能力。