关于Worker类与Threaded类
官方手册介绍,Worker类对象为Stackable(Threaded 网上资料说两者等同)类对象的容器,Worker对象通过Stack方法将Stackable(Threaded)类对象入栈。
Worker对象执行start()方法后,会调用run()方法,Worker类对象的特点是即使run方法执行完成后,线程仍保留上下文环境(内存封装的变量等),worker类对象执行完run方法后,如果栈非空则会调用stack中的Stackable(Threaded)类对象的run方法;如果栈空,则等待。直到调用Worker::shutdown结束线程。
通过对Worker类对象栈对象run方法的观察,Worker类对象栈内的Stackable(Threaded)类对象是按入栈顺序进行单线程执行,即出栈一个Stackable(Threaded)对象,执行该对象的run方法,非并发执行。
贴出验证代码:
class MyWorker extends Worker{
public function run(){
printf("Worker now is running,Worker thread id is:%s.\n",$this->getThreadId());
}
}
class MyStackable extends Stackable{
protected $threadName;
public function __construct($name){
$this->threadName = $name;
}
public function run(){
printf("Stackable object %s now is doing the run method \n",$this->threadName);
$arr = array();
for ($i=0; $i <100000 ; $i++) {
$arr[$i] = $i*10;
}
printf("work now use memory:%d\n",memory_get_usage());
for ($i=0; $i <10000 ; $i++) {
//检验在输出时,是否被其他线程打断,判断线程是否并发执行
printf("\t Stackable element code line $i\n");
}
}
}
入口程序中代码:
入口程序中的代码执行是非阻塞的,会依次调用所有printf语句在屏幕输出。然后依次执行$worker栈内对象的run方法。在屏幕中观察输出语句的顺序发现,在MyStackable对象中for循环printf语句未被其他线程打断。即用Worker类管理线程,并不能达到并发执行的目的。
$worker = new MyWorker;
$worker->start();
printf("No work was added in the queue,now memory used:%d\n",memory_get_usage());
$work_1 = new MyStackable("work_1");
printf("Get stack size:%d\n",$worker->getStacked());
$work_2 = new MyStackable("work_2");
$work_3 = new MyStackable("work_3");
$work_4 = new MyStackable("work_4");
$work_5 = new MyStackable("work_5");
printf("Get stack size:%d\n",$worker->getStacked());
$worker->stack($work_1);
printf("Get stack size:%d\n",$worker->getStacked());
printf("Now add one work to the queue,now memory used:%d\n",memory_get_usage());
$worker->stack($work_2);
$worker->stack($work_3);
$worker->stack($work_4);
$worker->stack($work_5);
printf("Now add two work to the queue,now memory used:%d\n",memory_get_usage());
printf("Get stack size:%d\n",$worker->getStacked());