精华内容
参与话题
问答
  • pthreads

    2016-12-24 19:03:20
    pthreads: 简介: pthreads是一组允许用户在 PHP 中使用多线程技术的面向对象的API。它提供了创建多线程应用所需的全套工具,无论是 Web 应用还是控制台应用。通过使用Thread,Worker以及Threaded 对象,PHP应用...
    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

    2013-07-14 10:57:50
    Reference of Pthreads 1. http://www.cs.fsu.edu/~baker/realtime/restricted/notes/pthreads.html
    展开全文
  • pthreads support

    2020-12-08 22:48:26
    t bother with FSU Pthreads, it's too old of an implementation, even though you can make it to compile). I'd like to see a build with pthreads support, so that std::thread would work.</p><p>该...
  • <div><p>So we can have multiple implementations of Thread, Worker classes without collisions. And it will be clearer what are those classes and from where.</p><p>该提问来源于...krakjoe/pthreads</p></div>
  • Dropped pthreads

    2020-12-28 20:49:09
    <div><p>Removed the last references to pthreads. It was basically already out of use, unless one was using some custom-built ogre without thread support. Needs testing on windows.</p><p>该提问来源于...
  • 锁机制(lock) 是多线程编程中最...Pthreads提供了多种锁机制,常见的有: 1) Mutex(互斥量):pthread_mutex_*** 2) Spin lock(自旋锁):pthread_spin_*** 3) Condition Variable(条件变量):pthread_con_*** 4) R

    锁机制(lock) 是多线程编程中最常用的同步机制,用来对多线程间共享的临界区(Critical Section) 进行保护。

    Pthreads提供了多种锁机制,常见的有:
    1) Mutex(互斥量):pthread_mutex_***
    2) Spin lock(自旋锁):pthread_spin_***
    3) Condition Variable(条件变量):pthread_con_***
    4) Read/Write lock(读写锁):pthread_rwlock_***

    在多线程编中,根据应用场合的不同,选择合适的锁来进行同步,对多线程程序的性能影响非常大. 本文主要对 pthread_mutex 和 pthread_spinlock 两种锁制机进行比较,并讨论其适用的场合.

    1 Pthread mutex

    Mutex属于sleep-waiting类型的锁. 从 2.6.x 系列稳定版内核开始, Linux 的 mutex 都是 futex (Fast-Usermode-muTEX)锁.
    futex(快速用户区互斥的简称)是一个在Linux上实现锁定和构建高级抽象锁如信号量和POSIX互斥的基本工具。它们第一次出现在内核开发的2.5.7版;其语义在2.5.40固定下来,然后在2.6.x系列稳定版内核中出现。
    Futex 是由Hubertus Franke(IBM Thomas J. Watson 研究中心), Matthew Kirkwood,Ingo Molnar(Red Hat)和 Rusty Russell(IBM Linux 技术中心)等人创建的。
    Futex 是由用户空间的一个对齐的整型变量和附在其上的内核空间等待队列构成. 多进程或多线程绝大多数情况下对位于用户空间的futex 的整型变量进行操作(汇编语言调用CPU提供的原子操作指令来增加或减少),而其它情况下,则需要通过代价较大的系统调用来对位于内核空间的等待队列进行操作(如唤醒等待的进程/线程,或 将当前进程/线程放入等待队列). 除了多个线程同时竞争锁的少数情况外,基于 futex 的 lock 操作是不需要进行代价昂贵的系统调用操作的.
    .
    这种机制的核心思想是通过将大多数情况下非同时竞争 lock 的操作放到在用户空间来执行,而不是代价昂贵的内核系统调用方式来执行,从而提高了效率.

    Pthreads提供的Mutex锁操作相关的API主要有:
    1、 pthread_mutex_lock (pthread_mutex_t *mutex);
    2、 pthread_mutex_trylock (pthread_mutex_t *mutex);
    3、 pthread_mutex_unlock (pthread_mutex_t *mutex);

    因为源代码比较长,这里不做摘录,大家可以参考:
    glibc-2.12.2/nptl/pthread_mutex_lock.c

    2 Pthread spinlock

    spinlock,也称自旋锁,是属于busy-waiting类型的锁.在多处理器环境中, 自旋锁最多只能被一个可执行线程持有。如果一个可执行线程试图获得一个被争用(已经被持有的)自旋锁,那么该线程就会一直进行忙等待,自旋,也就是空转,等待锁重新可用。如果锁未被争用,请求锁的执行线程便立刻得到它,继续执行。

    一个被争用的自旋锁使得请求它的线程在等待锁重新可用时自旋,特别的浪费CPU时间,所以自旋锁不应该被长时间的持有。实际上,这就是自旋锁的设计初衷,在短时间内进行轻量级加锁。

    Kernel中的自旋锁不能够在能够导致睡眠的环境中使用。举个例子,一个线程A获得了自旋锁L;这个时候,发生了中断,在对应的中断处理函数B中,也尝试获得自旋锁L,就会中断处理程序进行自旋。但是原先锁的持有者只有在中断处理程序结束后,采用机会释放自旋锁,从而导致死锁。
    由于涉及到多个处理器环境下,spin lock的效率非常重要。因为在等待spin lock的过程,处理器只是不停的循环检查,并不执行其他指令。但即使这样, 一般来说,spinlock的开销还是比进程调度(context switch)少得多。这就是spin lock 被广泛应用在多处理器环境的原因

    Pthreads提供的与Spin Lock锁操作相关的API主要有:
    pthread_spin_lock (pthread_spinlock_t *lock);
    pthread_spin_trylock (pthread_spinlock_t *lock);
    pthread_spin_unlock (pthread_spinlock_t *lock);

    展开全文
  • php线程pthreads扩展

    2019-04-26 16:25:16
    php线程pthreads扩展:包含php7.0.1版本和php5.5.38两个版本和官网一致
  • 1、安装多线程库:cd /usr/local/services/php-7.0.7/bin/pecl install pthreads或手动编译安装:wget ...

    1、安装多线程库:

    cd /usr/local/services/php-7.0.7/bin/pecl install pthreads

    或手动编译安装:

    wget http://www.xxx.com/pecl.php.net/get/pthreads-3.1.6.tgz

    tar -zxvf pthreads-3.1.6.tgz

    cd pthreads-3.1.6

    /usr/local/services/php-7.0.7//bin/phpize

    ./configure --with-php-config=/usr/local/services/php-7.0.7/bin/php-config

    make && make install

    2、配置文件

    编辑/usr/local/services/php-7.0.7/etc/php.ini加上extension=pthreads.so

    运行查看安装是否成功

    /usr/local/services/php-7.0.7/bin/php -m

    3、php-fpm

    支持 PHP 7 的 pthreads v3 只支持通过 cli 命令行来调用,不支持其他的 sapi,所以

    执行/usr/local/services/php-7.0.7/sbin/php-fpm 出错:

    [23-Jun-2018 02:14:44 UTC] PHP Fatal error: The fpm-fcgi SAPI is not supported by pthreads in Unknown on line 0

    [23-Jun-2018 02:14:44 UTC] PHP Fatal error: Unable to start pthreads module in Unknown on line 0

    解决:

    CLI模式下,php会优先读取php-cli.ini,如果没找到会使用php.ini

    【1】cp php.ini php-cli.ini 添加扩展pthreads

    extension=pthreads.so

    【2】编辑原来的php.ini文件注释掉pthreads扩展

    ;extension=pthreads.so

    这样CLI模式下php-cli.ini生效,而php-fpm不会读php-cli.ini

    展开全文
  • <ul><li>PHP: 7.2.14 (cli) ( ZTS )</li><li>decimal: 1.1.1</li><li>pthreads: 3.2.0 (http://php.net/manual/en/book.pthreads.php / https://github.com/krakjoe/pthreads)</li><li>libmpdec: 2.4.2</li><li>OS: ...
  • Building with PThreads

    2021-01-11 03:12:10
    <div><p>Looking to build an application that utilizes PThreads, however, it doesn't build. The error below is generated, it seems to be an issue with conan code that includeOS is using to build ...
  • <div><p>I'...<p>First I connect to server with my URI then I pass my ... Pthreads version: php_pthreads-3.1.6-7.0-ts-vc14-x86</p><p>该提问来源于开源项目:planetteamspeak/ts3phpframework</p></div>
  • Pthreads Programming

    热门讨论 2011-05-05 11:38:12
    It's been quite a while since the people from whom we get our project assignments accepted... This book is about Pthreads—a lightweight, easy-to-use, and portable mechanism for speeding up applications.
  • http://www.searchtb.com/2011/01/pthreads-mutex-vs-pthread-spinlock.html 锁机制(lock) 是多线程编程中最常用的同步机制,用来...Pthreads提供了多种锁机制,常见的有: 1) Mutex(互斥量):pthread_mutex_
  • Php 7.2 with pthreads fails

    2021-01-09 04:15:47
    turn on --enabled-maintainer-zts and --enable-pthreads. build fails <h1>Reproducing Code <p>apt-get source php7.2 cd ext git clone https://github.com/krakjoe/pthreads.git DEB_BUILD_OPTIONS=nocheck...
  • Pthreads编程入门

    2019-11-15 09:55:59
    Pthreads编程入门 本文为并行程序设计导论部分第四章的总结,读者可结合书本内容一起理解 Pthreas介绍 POSIX线程(英语:POSIX Threads,常被缩写为Pthreads)是POSIX的线程标准,定义了创建和操纵线程的一套API。 ...
  • pthreads手册

    千次阅读 2013-05-17 16:44:09
    原文地址:http://man7.org/linux/man-pages/man7/pthreads.7.html   PTHREADS(7) Linux Programmer's Manual PTHREADS(7)   NAME top pthreads - POSIX threads
  • Unittests Disable pthreads

    2021-01-09 11:28:33
    <p>I want to compile my unittests without pthreads (gtest_disable_pthreads=ON), but I dont find the file where I need to add this flag and with the CLI its not possible to attach flags. So my ...
  • pthreads and yii2

    2021-01-09 04:11:59
    m using pthreads together with yii2. I would like to use in class Stackable Model Yii. How do I do this? In the Yii are tied to namespase. </p><p>该提问来源于开源项目:krakjoe/pthreads</p></div>
  • MongoDB and pthreads

    2021-01-09 04:12:23
    <div><p>Joe, good afternoon. <p>Is it possible to multi-thread mongodb driver and iterators? Now when you try to execute the following code: ...<?... // one provider for several...krakjoe/pthreads</p></div>
  • <div><p>I've been hunting this segfault for quite some time as it happens very rarely and looks like a race condition. Running the program under gdb used to prevent it ...krakjoe/pthreads</p></div>
  • t the ability to enable/disable pthreads in apache be up to the user who's environment is at stake? Please enable pthreads with apache support off by default and allow the user to turn it on.</p>...
  • Pthreads for Windows support

    2020-11-20 22:19:22
    <div><p>Support for pthreads and GCC on Windows. Fixes #92. Still needs to be tested with MinGW and Clang.</p><p>该提问来源于开源项目:Blosc/c-blosc</p></div>
  • pthreadsA fair amount has changed for the pthreads extension with the release of pthreads v3. This article aims to cover the necessary information for those who are looking to upgrade their applicatio...
  • 5.14. pthreads

    2017-12-27 11:21:00
    编译PHP时需要加入 --enable-maintainer-zts 选项才能安装pthreads # pecl install pthread 配置文件 cat > /srv/php-5.5.7/etc/conf.d/pthreads.ini <...extension=pthreads.so EOF $ php ...
  • pthreads 教程

    2013-12-26 20:21:36
    [url]https://computing.llnl.gov/tutorials/pthreads/[/url]

空空如也

1 2 3 4 5 ... 20
收藏数 3,820
精华内容 1,528
关键字:

pthreads