pthreads:
简介:
pthreads是一组允许用户在 PHP 中使用多线程技术的面向对象的API。它提供了创建多线程应用所需的全套工具,无论是 Web 应用还是控制台应用。通过使用Thread,Worker以及Threaded 对象,PHP应用可以创建、读取、写入以及执行多线程应用,并可以在多个线程之间进行同步控制。
1.Threaded 对象: Threaded 对象提供支持 pthreads 操作的基本功能,包括同步方法以及其他对程序员很有帮助的接口。
2.Thread 对象: 通过继承 pthreads 中提供的 Thread 对象并实现 run 方法,用户可以创建自己的 Thread 对象。 只要线程上下文中持有某个 Thread 对象的引用,就可以读/写该对象的属性,也可以调用该对象的公有(public)或者受保护(protected)的方法。 当在创建 Thread 对象的进程或线程上下文中调用该对象的 start 方法时,pthreads 扩展会在另外的独立线程中执行该对象的 run 方法。 仅有创建 Thread 对象的线程/进程方可开始(start)或者加入(join)这个 Thread 对象。
3.Worker 对象: Worker 是有状态的线程对象,它在线程开始之后就可用,除非代码中显式地关闭线程,否则该对象在线程对象超出作用范围之后才会失效。 持有 Worker 对象引用的线程上下文可以向 Worker 中入栈其他线程对象,Worker 对象将在独立线程中执行入栈对象的代码。 Woker 对象的 run 方法会在它的栈中入栈对象之前执行,这样就可以进行一些必需的资源初始化工作。
4.Pool 对象: Pool 对象是 Worker 线程对象池,可以用来在多个 Worker 对象之间分发 Threaded 对象,它可以很好的处理对象应用。 Pool 对象从 1.0.0 版本开始引入,现在已经成为最易用且高效多线程编程方式。
注意:Pool 是标准 PHP 对象,所以不可以在多个线程上下文中共享同一个 Pool 对象。
5.线程间同步: 由 pthreads 扩展创建的所有对象拥有内置的线程间同步机制,和 Java 语言很类似,使用 ::wait 和 :: notify 方法。 调用某一个对象的 ::wait 方法会导致当前线程上下文进入等待状态,等待另外一个线程上下文调用同一个对象的 ::notify 方法。 为 PHP Threaded 对象提供了强有力的线程间同步控制机制。
注意:应用中会用在多线程场景中的对象都应该从 Threaded 类继承。
6.方法修饰符: Threaded 对象中的受保护方法(protected)是被 pthreads 保护的,也就是说,在同一时间,只有一个线程可以访问该方法。 在执行过程中,私有方法(private)只能被该对象本身调用。
7.数据存储: 一般来说,任何可以序列化的数据类型都可以作为 Threaded 对象的属性,它可以从持有该对象引用的任何线程上下文读/写。 并不是所有的数据都采用序列化方式存储,比如基本类型就是以其真实形态存储的。 对于不是 Threaded 派生的对象,例如复杂类型、数组以及对象等,都是序列化存储的,可以从持有 Threaded 对象引用的任何线程上下文中读取和写入, 区别就在于对于 Threaed 的派生对象,设置它的成员变量的过程是在独立线程上下文中执行的。 对于 Threaded 派生对象,在同一时间,不同的线程上下文都可以从该对象中读取到同样的数据。
8.静态成员: 当创建新的线程上下文(Thread 或 Worker 对象)的时候,静态成员会被拷贝到新的上下文中。出于安全考虑,资源类型以及包含内部状态的对象类型的静态成员会被置空。 实际上这个特性实现了类似线程本地存储的功能。举例说明,假设某个类拥有包含数据库连接信息以及数据库连接对象静态成员, 那么当新的线程上下文启动的时候,仅有数据库连接信息会被复制到新上下文中,而数据库连接对象并不会被复制。 所以,需要在新的上下文中根据复制过来的数据库连接基本信息来初始化数据库连接对象,新创建的数据库连接对象是独立的, 不影响在原上下文中的数据库连接对象。
注意1:当使用 print_r, var_dump 或者其他函数来进行对象调试的时候,是没有递归保护机制的。
注意2:资源类型: PHP 中很多使用到 Resource 资源类型的扩展或函数并未针对多线程场景进行特殊设计,也就是说,虽然 pthreads 扩展提供了 在多个线程上下文中共享资源类型变量的能力,但是通常来说,你应该把它们视为非线程安全的。 所以,如果要在多个线程上下文中共享资源类型的变量,你应该特别谨慎对待。
注意3:为了提供一个稳定的运行环境,pthreads 扩展在执行过程中会有一些必需的额外限制。
预定义常量:
PTHREADS_INHERIT_ALL - 线程的默认选项。线程开始的时候,pthreads 扩展会将环境复制到线程上下文中。
PTHREADS_INHERIT_NONE - 新线程开始时,不继承任何内容。
PTHREADS_INHERIT_INI - 新线程开始时,仅继承 INI 配置。
PTHREADS_INHERIT_CONSTANTS - 新线程开始时,继承用户定义的常量。
PTHREADS_INHERIT_CLASSES - 新线程开始时,继承用户定义的类。
PTHREADS_INHERIT_FUNCTIONS - 新线程开始时,继承用户定义的函数。
PTHREADS_INHERIT_INCLUDES - 新线程开始时,继承包含文件。
PTHREADS_INHERIT_COMMENTS - 新线程开始时,继承所有的注释。
PTHREADS_ALLOW_HEADERS - 允许新线程向标准输出发送头信息(通常情况下是被禁止的)。
Threaded类:
简介:
Threaded 对象提供支持 pthreads 操作的基本功能,包括同步方法以及其他对程序员很有帮助的接口。
重要的是,Threaded 提供了隐式的线程安全机制,这个对象中的所有操作都是线程安全的。
方法:
public array Threaded::chunk ( integer $size , boolean $preserve )
获取给定数量的对象属性表,可以选择是否保留键名称
参数:
$size - 要获取的条目数量
$preserve - 保留成员原有的键名称,默认为false
示例:
// 获取对象属性表中的部分条目
<?php
$safe = new Threaded();
while(count($safe) < 10){
$safe[] = count($safe);
}
var_dump($safe->chunk(5));
?>
返回值:
array(5){
[0]=> int(0)
[1]=> int(1)
[2]=> int(2)
[3]=> int(3)
[4]=> int(4)
}
public integer Threaded::count ( void )
返回对象的属性数量
示例:
// 计算对象中的属性数量
<?php
$safe = new Threaded();
while(count($safe) < 10){
$safe[] = count($safe);
}
var_dump(count($safe)); // -------- 手册这里是不是错了??并未调用count()方法
var_dump($safe->count()); // -------- 应该是这个吧
?>
返回值:
int(10)
public bool Threaded::extend ( string $class )
在运行时,扩展指定的类为线程安全的标准类
参数:
$class - 要扩展的类
返回值:
true | false,表示是否扩展成功
示例:
<?php
class My {}
Threaded::extend(My::class); // 扩展 'My'
$my = new My();
var_dump($my instanceof Threaded); // 如果也是 'Threaded' 的示例,说明扩展成功
?>
public Threaded Threaded::from ( Closure $run [, Closure $construct [, array $args ]] )
通过闭包创建一个匿名的Threaded对象
参数:
$run - ::run()方法使用的闭包
$construct - 匿名对象使用的构造方法
$args - 传递给构造方法的参数
返回值:
返回一个新的匿名的Threaded对象
示例:
// 来自闭包的线程安全的对象(完全和方法看到的不同啊,可能$pool实现了Threaded类,还未看到)
<?php
$pool = new Pool(4);
$pool->submit(Collectable::from(function(){
echo "Hello World";
$this->setGarbage();
}));
/* ... */
$pool->shutdown();
?>
输出:
hello world
public array Threaded::getTerminationInfo ( void )
返回对象的终端错误信息(该方法由Thread实现)
示例:
// 检测线程运行时的致命错误
<?php
class My extends Thread {
public function run() {
@not_found();
}
}
$my = new My();
$my->start();
$my->join();
var_dump($my->isTerminated(), $my->getTerminationInfo());
?>
返回值:
bool(true)
array(4) {
["scope"]=>
string(2) "My"
["function"]=>
string(3) "run"
["file"]=>
string(29) "/usr/src/pthreads/sandbox.php"
["line"]=>
int(4)
}
public boolean Threaded::isRunning ( void )
对象是否正在运行
注意:
如果对象的run方法正在执行,则视该对象为处于运行状态。返回 true | false
示例:
<?php
class My extends Thread {
public function run() {
$this->synchronized(function($thread){
if (!$thread->done)
$thread->wait();
}, $this);
}
}
$my = new My();
$my->start();
var_dump($my->isRunning());
$my->synchronized(function($thread){
$thread->done = true;
$thread->notify();
}, $my);
?>
返回值:
bool(true)
public boolean Threaded::isTerminated ( void )
检测是否因致命错误或未捕获的异常而导致执行过程异常终止
示例:
<?php
class My extends Thread {
public function run() {
i_do_not_exist();
}
}
$my = new My();
$my->start();
$my->join();
var_dump($my->isTerminated());
?>
返回值:
bool(true)
public boolean Threaded::isWaiting ( void )
检测对象是否在等待其他线程唤醒
示例:
<?php
class My extends Thread {
public function run() {
$this->synchronized(function($thread){
if (!$this->done)
$thread->wait();
}, $this);
}
protected $done;
}
$my = new My();
$my->start();
$my->synchronized(function($thread){
var_dump(
$thread->isWaiting());
$thread->done = true;
$thread->notify();
}, $my);
?>
返回值:
bool(true)
public boolean Threaded::lock ( void )
给对象属性表加锁
示例:
<?php
class My extends Thread {
public function run() {
var_dump($this->lock());
/** 其他线程无法进行读/写操作 **/
var_dump($this->unlock());
/** 其他线程可以进行读/写操作 */
}
}
$my = new My();
$my->start();
?>
返回值:
bool(true)
bool(true)
public boolean Threaded::unlock ( void )
从调用上下文中解锁被引用的对象
示例:
<?php
class My extends Thread {
public function run() {
var_dump($this->lock());
/** 其他线程无法进行读/写操作 **/
var_dump($this->unlock());
/** 其他线程可以进行读/写操作 */
}
}
$my = new My();
$my->start();
?>
返回值:
bool(true)
bool(true)
public boolean Threaded::merge ( mixed $from [, mixed $overwrite ] )
将数据合并到当前对象
参数:
$from - 要合并的数据
$overwrite - 如果现有对象已经存在同键的数据,是否覆盖。默认为 true
示例:
// 合并数据到对象的属性表
<?php
$array = [];
while (count($array) < 10)
$array[] = count($array);
$stdClass = new stdClass();
$stdClass->foo = "foo";
$stdClass->bar = "bar";
$stdClass->baz = "baz";
$safe = new Threaded();
$safe->merge($array);
$safe->merge($stdClass);
var_dump($safe);
?>
返回值:
object(Threaded)#2 (13) {
["0"]=> int(0)
["1"]=> int(1)
["2"]=> int(2)
["foo"]=> string(3) "foo"
["bar"]=> string(3) "bar"
["baz"]=> string(3) "baz"
}
public boolean Threaded::notify ( void )
向对象发送唤醒通知
示例:
// 等待和唤醒
<?php
class My extends Thread {
public function run() {
/** 让线程等待 **/
$this->synchronized(function($thread){
if (!$thread->done)
$thread->wait();
}, $this);
}
}
$my = new My();
$my->start();
/** 向处于等待状态的线程发送唤醒通知 **/
$my->synchronized(function($thread){
$thread->done = true;
$thread->notify();
}, $my);
var_dump($my->join());
?>
返回值:
bool(true)
public mixed Threaded::synchronized ( Closure $block [, mixed $... ] )
在发起调用的线程上下文中获取对象同步锁,然后同步执行代码块
参数:
$block - 要执行的代码块
... - 传送给代码块的不定长参数
返回值:
代码块的返回值
示例:
// 同步
<?php
class My extends Thread {
public function run() {
$this->synchronized(function($thread){
if (!$thread->done)
$thread->wait();
}, $this);
}
}
$my = new My();
$my->start();
$my->synchronized(function($thread){
$thread->done = true;
$thread->notify();
}, $my);
var_dump($my->join());
?>
返回值:
bool(true)
public void Threaded::run ( void )
如果需要在多线程环境下执行代码,必须实现本方法 -------- 由Thread类实现
返回值:
无返回值。即使代码中 run 方法有返回值,也会被忽略
public boolean Threaded::wait ([ integer $timeout ] )
让发起调用的线程上下文进入等待状态,直到收到其他线程的唤醒通知
参数:
$tiemout - 可选参数,等待时间,以毫秒计
示例:
// 等待和唤醒
<?php
class My extends Thread {
public function run() {
/** 让线程等待 **/
$this->synchronized(function($thread){
if (!$thread->done)
$thread->wait();
}, $this);
}
}
$my = new My();
$my->start();
/** 向处于等待状态的线程发送唤醒通知 **/
$my->synchronized(function($thread){
$thread->done = true;
$thread->notify();
}, $my);
var_dump($my->join());
?>
返回值:
bool(true)
public mixed Threaded::pop ( void )
弹出对象属性表中的最后一项数据
示例:
<?php
$safe = new Threaded();
while (count($safe) < 10)
$safe[] = count($safe);
var_dump($safe->pop());
?>
输出:
int(9)
public mixed Threaded::shift ( void )
弹出对象属性表中的第一项数据
示例:
<?php
$safe = new Threaded();
while (count($safe) < 10)
$safe[] = count($safe);
var_dump($safe->shift());
?>
输出:
int(0)
Thread类:
简介:
当调用Thread对象的start方法时,该对象的run方法中的代码将在独立线程中异步执行.
run 方法中的代码执行完毕之后,独立线程立即退出,并且等待合适的时机由创建者线程加入(join)。
注意:
依赖于引擎本身的机制检测何时加入线程可能引发非预期的行为,程序员应该尽可能的显式控制线程加入的时机。
方法:
Thread extends Threaded implements Countable , Traversable , ArrayAccess
因此方法包括2部分:1.自己实现的方法;2.继承自Threaded的方法
public void Thread::detach ( void )
从调用上下文中将引用线程分离出来,非常危险!
警告:
本方法会引发未定义的、不安全的行为。 通常情况下不会用到本方法,提供这个方法主要是出于完备性以及高级用法的考虑。
public integer Thread::getCreatorId ( void )
返回创建当前线程的线程ID
示例:
<?php
class My extends Thread {
public function run() {
printf("%s created by Thread #%lu\n", __CLASS__, $this->getCreatorId());
}
}
$my = new My();
$my->start();
?>
返回值:
My created by Thread #123456778899
public static Thread Thread::getCurrentThread ( void )
获取当前执行线程的引用,返回当前执行线程的对象
示例:
<?php
class My extends Thread {
public function run() {
var_dump(Thread::getCurrentThread());
}
}
$my = new My();
$my->start();
?>
返回值:
object(My)#2 (0) {
}
public static integer Thread::getCurrentThreadId ( void )
返回当前执行线程的ID
示例:
<?php
class My extends Thread {
public function run() {
printf("%s is Thread #%lu\n", __CLASS__, Thread::getCurrentThreadId());
}
}
$my = new My();
$my->start();
?>
返回值:
My is Thread #123456778899
public integer Thread::getThreadId ( void )
返回引用线程的ID
示例:
<?php
class My extends Thread {
public function run() {
printf("%s is Thread #%lu\n", __CLASS__, $this->getThreadId());
}
}
$my = new My();
$my->start();
?>
返回值:
My is Thread #123456778899
public static mixed Thread::globally ( void )
在全局范围中执行代码块
示例:
// 在全局范围执行代码块
<?php
class My extends Thread {
public function run() {
global $std;
Thread::globally(function(){
$std = new stdClass;
});
var_dump($std);
}
}
$my = new My();
$my->start();
?>
返回值:
// 被调用代码块的返回值
object(stdClass)#3 (0) {
}
public boolean Thread::isJoined ( void )
线程是否已经被加入(join)
示例:
// 检测线程状态
<?php
class My extends Thread {
public function run() {
$this->synchronized(function($thread){
if (!$thread->done)
$thread->wait();
}, $this);
}
}
$my = new My();
$my->start();
var_dump($my->isJoined());
$my->synchronized(function($thread){
$thread->done = true;
$thread->notify();
}, $my);
?>
返回值:
bool(false)
public boolean Thread::isStarted ( void )
线程是否开始执行
示例:
// 检测线程是否开始执行
<?php
$worker = new Worker();
$worker->start();
var_dump($worker->isStarted());
?>
返回值:
bool(true)
public boolean Thread::join ( void )
让当前执行上下文等待被引用线程执行完毕
示例:
// 加入线程
<?php
class My extends Thread {
public function run() {
/* ... */
}
}
$my = new My();
$my->start();
/* ... */
var_dump($my->join());
/* ... */
?>
返回值:
bool(true)
public void Thread::kill ( void )
强制线程终止
警告:
通常情况下,程序员不应该强制杀除线程
示例:
// 杀除线程
<?php
class T extends Thread {
public function run() {
$stdin = fopen("php://stdin", "r");
while(($line = fgets($stdin))) {
echo $line;
}
}
}
$t = new T();
$t->start();
var_dump($t->kill());
?>
返回值:
bool(true)
public boolean Thread::start ([ integer $options ] )
在独立线程中执行run方法
参数:
$options - 可选参数,用来控制线程继承。默认值为 PTHREADS_INHERIT_ALL
示例:
// 开始线程
<?php
class My extends Thread {
public function run() {
/** ... **/
}
}
$my = new My();
var_dump($my->start());
?>
返回值:
bool(true)
Worker类:
简介:
Worker 是一个具有持久化上下文的线程对象,通常用来重复使用线程。
当一个 Worker 对象开始之后,会执行它的 run 方法,但是即使 run 方法执行完毕,线程本身也不会消亡,除非遇到以下情况:
1.Worker 对象超出作用范围(没有指向它的引用了)
2.代码调用了 Worker 对象的 shutdown 方法
3.整个脚本终止了
这意味着程序员可以在程序执行过程中重用这个线程上下文:在 Worker 对象的栈中添加对象会激活 Worker 对象执行被加入对象的 run 方法。
警告:
程序员必须保持入栈对象的引用,直到它执行完毕或者出栈。Pool 类提供了 Worker 对象的高层抽象, 它可以帮助程序员管理这些引用。
方法:
Worker extends Thread implements Traversable , Countable , ArrayAccess
public integer Worker::getStacked ( void )
返回等待被 Worker 对象执行的对象数量
示例:
// 返回等待 Worker 执行的对象数量
<?php
class Work extends Threaded {
/** ... **/
public function run(){
/** ... **/
}
}
$my = new Worker();
/** ... **/
$work = new Work();
$my->stack($work);
/** ... **/
printf("My worker has %d jobs remaining\n", $my->getStacked());
/** ... **/
?>
返回值:
My worker has 5 jobs remaining
public integer Worker::stack ( Threaded &$work )
将对象入栈到 Worker 对象
参数:
$work - 要被 Worker 执行的Threaded 派生对象
示例:
// 向 Worker 中入栈对象并执行
<?php
class Work extends Threaded {
/** ... **/
public function run(){
/** ... **/
}
}
$my = new Worker();
$work = new Work();
/** ... **/
var_dump($my->stack($work));
/** ... **/
?>
返回值 - Worker对象栈的长度:
int(1)
public integer Worker::unstack ([ Threaded &$work ] )
从 Worker 栈中出栈对象,如果不提供参数,则表示移除 Worker 栈中全部对象
参数:
要移除的栈对象
示例:
// 从Worker栈中移除对象
<?php
class Work extends Threaded {
public function run() {
}
}
$my = new Worker();
$work = new Work();
var_dump($my->stack($work));
var_dump($my->unstack($work));
?>
返回值 - Worker对象栈的长度:
int(1)
int(0)
public boolean Worker::shutdown ( void )
在执行完已入栈对象之后,关闭这个 Worker 对象
示例:
// 关闭Worker
<?php
$my = new Worker();
$my->start();
/* ... */
var_dump($my->shutdown());
/* ... */
?>
返回值:
bool(true)
public boolean Worker::isWorking ( void )
Worker 对象是否正在执行栈中对象
示例:
<?php
// 检测Worker对象状态
$my = new Worker();
$my->start();
/* ... */
if ($my->isWorking()) {
/* ... the Worker is busy executing another object */
}
?>
返回值:
bool(true)
public boolean Worker::isShutdown ( void )
Worker对象是否被关闭
示例:
<?php
// 检测Worker状态
$my = new Worker();
$my->start();
var_dump($my->isShutdown());
$my->shutdown();
var_dump($my->isShutdown());
?>
返回值:
bool(false)
bool(true)
Collectable类:
简介:
Collectable代表一个垃圾回收对象
Collectable对象倾向于被 Pool 类使用,用来替代Threaded对象,作为工作单位。它可以提供设置和检测一个对象的可回收性。
方法:
Collectable extends Threaded
public bool Collectable::isGarbage ( void )
可在 Pool::collect() 中调用,来判断对象是垃圾、可回收
public void Collectable::setGarbage ( void )
当对象执行完毕、或引用完毕,应该被调用,一个对象只应该调用一次
Pool类:
简介:
Pool 对象是多个 Worker 对象的容器,同时也是它们的控制器。
线程池是对 Worker 功能的高层抽象,包括按照 pthreads 需要的方式来管理应用的功能。
属性:
size - Pool 对象可容纳的 Worker 对象的最大数量
class - Worker 的类
ctor - 构造新的 Worker 对象时所需的参数
workers - 指向 Worker 对象的引用
work - 指向提交到 Pool 对象中的 Threaded 对象的引用
last - 最后使用的 Worker 对象在池中的位置偏移量
方法:
public Pool Pool::__construct ( integer $size , string $class [, array $ctor ] )
创建新的Worker对象池
参数:
$size - 此Pool对象可创建的Worker对象的最大数量
$class - 新创建的Worker对象的类
$ctor - 创建Worker对象时所用到的参数,以数组方式传入
示例:
// 创建 Pool 对象
<?php
class MyWorker extends Worker {
public function __construct(Something $something) {
$this->something = $something;
}
public function run() {
/** ... **/
}
}
$pool = new Pool(8, \MyWorker::class, [new Something()]);
var_dump($pool);
?>
返回值 - 新创建的 Pool 对象:
object(Pool)#1 (6) {
["size":protected]=>
int(8)
["class":protected]=>
string(8) "MyWorker"
["workers":protected]=>
NULL
["work":protected]=>
NULL
["ctor":protected]=>
array(1) {
[0]=>
object(Something)#2 (0) {
}
}
["last":protected]=>
int(0)
}
public void Pool::collect ( Callable $collector )
对于视为垃圾的引用,使用给定的垃圾收集器进行收集
参数:
$collector - 可调用的垃圾收集器
示例:
// 手册上有人说,手册上给定的例子是错误的,浪费了他2天时间,纠正后的示例
<?php
class MyWork extends Thread {
protected $complete;
public function __construct() {
$this->complete = false;
}
public function run() {
printf(
"Hello from %s in Thread #%lu\n",
__CLASS__, $this->getThreadId());
$this->complete = true;
}
public function isComplete() {
return $this->complete;
}
}
class Something {}
class MyWorker extends Worker {
public function __construct(Something $something) {
$this->something = $something;
}
public function run() {
/** ... **/
}
}
$pool = new Pool(8, \MyWorker::class, [new Something()]);
$pool->submit(new MyWork());
usleep(1000);
$pool->collect(function($work){
return $work->isComplete();
});
var_dump($pool);
?>
public void Pool::resize ( integer $size )
改变 Pool 对象的可容纳 Worker 对象的数量
参数:
$size - 此 Pool 对象可创建 Worker 对象的最大数量
public integer Pool::submit ( Threaded $task )
将任务提交到 Pool 中的下一个 Worker 对象
参数:
$task - 要执行的任务
返回值:
执行新加入对象的 Worker 对象ID
示例:
// 提交任务
<?php
class MyWork extends Threaded {
public function run() {
/* ... */
}
}
class MyWorker extends Worker {
public function __construct(Something $something) {
$this->something = $something;
}
public function run() {
/** ... **/
}
}
$pool = new Pool(8, \MyWorker::class, [new Something()]);
$pool->submit(new MyWork());
var_dump($pool);
?>
输出:
object(Pool)#1 (6) {
["size":protected]=>
int(8)
["class":protected]=>
string(8) "MyWorker"
["workers":protected]=>
array(1) {
[0]=>
object(MyWorker)#4 (1) {
["something"]=>
object(Something)#5 (0) {
}
}
}
["work":protected]=>
array(1) {
[0]=>
object(MyWork)#3 (1) {
["worker"]=>
object(MyWorker)#5 (1) {
["something"]=>
object(Something)#6 (0) {
}
}
}
}
["ctor":protected]=>
array(1) {
[0]=>
object(Something)#2 (0) {
}
}
["last":protected]=>
int(1)
}
public integer Pool::submitTo ( integer $worker , Threaded $task )
将对象提交到 Pool 中某个 Worker 对象来执行
参数:
$worker - 用来执行任务的 Worker 对象
$task - 要执行的任务
public void Pool::shutdown ( void )
停止此 Pool 中所有的 Worker 对象
Mutex类:
简介:
Mutex 类中包含一些直接访问 Posix 互斥量的静态方法
方法:
final public static long Mutex::create ([ boolean $lock ] )
为调用者创建一个互斥量,同时也可以通过 lock 参数设置是否在创建完成之后立即加锁此互斥量
参数:
$lock - 如果设置 lock 参数为 true,表示创建互斥量之后,立即加锁,然后再将互斥量句柄返回给调用者
返回值:
新创建的互斥量句柄,这个互斥量可能已经处于加锁状态,由 lock 参数控制
示例:
<?php
/** 不可以使用 new 关键字,因为互斥量不是 PHP 对象 **/
$mutex = Mutex::create();
/** 你已经持有了这个互斥量的物理地址 **/
var_dump($mutex);
/** 不要忘记销毁你创建的互斥量 **/
Mutex::destroy($mutex);
?>
输出:
int(40096976)
final public static boolean Mutex::destroy ( long $mutex )
当不再使用某个已经创建的互斥量句柄之后,程序员需要显式的销毁它。
参数:
$mutex - 通过调用函数 Mutex::create() 返回的互斥量句柄。 当调用 Mutex::destroy() 函数之后,任何线程都无法再给这个互斥量加锁了。
final public static boolean Mutex::lock ( long $mutex )
尝试为调用者给互斥量加锁。
尝试给已经被其他线程加锁的互斥量再次加锁会导致调用者线程进入阻塞状态。
参数:
$mutex - 通过调用函数 Mutex::create() 产生的互斥量句柄。
示例:
// 互斥量加锁与解锁
<?php
/** 不可以使用 new 关键字,因为互斥量不是 PHP 对象 **/
$mutex = Mutex::create();
/** 现在可以在任何线程上下文中给这个互斥量加锁了 **/
var_dump(Mutex::lock($mutex));
/** 销毁一个处于加锁状态的互斥量的操作是无效的 **/
var_dump(Mutex::unlock($mutex));
/** 永远不要忘记销毁你创建的互斥量 **/
Mutex::destroy($mutex);
?>
输出:
bool(true)
bool(true)
final public static boolean Mutex::unlock ( long $mutex [, boolean $destroy ] )
尝试为互斥量解锁,也可以通过 destroy 参数控制是否在解锁之后同时销毁此互斥量。 只有持有互斥量锁的线程才可以对这个互斥量进行解锁操作。
参数:
$mutex - 通过调用函数 Mutex::create() 产生的互斥量句柄。
$destroy - 此参数为 true 表示如果解锁成功,则同时销毁此互斥量。
final public static boolean Mutex::trylock ( long $mutex )
尝试给一个互斥量加锁,即使这个互斥量已经被其他线程锁定,也不会导致调用者线程进入阻塞状态。
参数:
$mutex - 通过调用函数 Mutex::create() 产生的互斥量句柄。
Cond类:
简介:
Cond 类提供一组用来直接访问 Posix 条件变量的静态方法。
方法:
final public static long Cond::create ( void )
创建一个条件变量
返回值:
指向条件变量的句柄。
示例:
// 条件变量的创建与销毁
<?php
/** 不可以使用 new 关键字,因为 Cond 不是 PHP 对象 **/
$cond = Cond::create();
/** 现在你可以在任意线程上下文中使用此条件变量 **/
var_dump($cond);
/** 永远不要忘记销毁你创建的条件变量 **/
Cond::destroy($cond);
?>
输出:
int(4540682)
final public static boolean Cond::destroy ( long $condition )
当不再需要所创建的条件变量时,程序员必须显式的销毁它。 当调用 Cond::destroy() 函数时,必须保证其他线程没有处于等待此条件变量的阻塞状态(通过调用函数 Cond::wait() 进入条件阻塞状态)。
参数:
$condition - 通过调用 Cond::create() 函数获得的条件变量句柄
final public static boolean Cond::broadcast ( long $condition )
向所有由于调用 Cond::wait() 函数而进入条件阻塞状态的线程发送广播。
参数:
$condition - 通过调用 Cond::create() 函数获得的条件变量句柄
示例:
// 广播条件变量
<?php
/** 不可以使用 new 关键字,因为 Cond 不是 PHP 对象 **/
$cond = Cond::create();
/** 调用者必须给关联的互斥量加锁,然后才可以进行广播(调用 broadcast 方法) **/
var_dump(Cond::broadcast($cond));
/** 永远不要忘记销毁你创建的条件变量 **/
Cond::destroy($cond);
?>
输出:
bool(true)
final public static boolean Cond::wait ( long $condition , long $mutex [, long $timeout ] )
进入条件变量等待状态。通过 timeout 参数可以设置等待超时时间。
参数:
$condition - 通过调用 Cond::create() 函数获得的条件变量句柄
$mutex - 通过调用 Mutex::create() 函数获得的互斥量,并且已经被调用者线程加锁。
$timeout - 等待超时,以毫秒为单位。
示例:
// 等待条件变量
<?php
/** 请注意,本示例会导致进程挂起 **/
$mutex = Mutex::create(true);
/** 不可以使用 new 关键字,因为 Cond 不是 PHP 对象 **/
$cond = Cond::create();
/** The caller must lock the associated Mutex before a call to broadcast **/
var_dump(Cond::wait($cond, $mutex));
/** 永远不要忘记销毁你创建的条件变量及互斥量 **/
Cond::destroy($cond);
Mutex::unlock($mutex);
Mutex::destroy($mutex);
?>
输出:
int(49685473)
final public static boolean Cond::signal ( long $condition )
发送唤醒信号
参数:
$condition - 通过调用 Cond::create() 函数获得的条件变量句柄
示例:
<?php
/** 不可以使用 new 关键字,因为 Cond 不是 PHP 对象 **/
$cond = Cond::create();
/** 调用者必须持有关联的互斥量锁,然后才可以进行唤醒信号发送(调用 signal 方法) **/
var_dump(Cond::signal($cond));
/** 永远不要忘记销毁你创建的条件变量 **/
Cond::destroy($cond);
?>
输出:
bool(true)
参考笔记:http://netkiller.github.io/journal/thread.php.html
pthreads
最新推荐文章于 2022-05-18 10:11:35 发布