考虑以下代码,这很不言自明:
<?php
class TestController extends BaseController {
public static $buffer,$num,$stderr;
public static function test(){
//phpinfo();
//print_r(class_exists('Thread'));
//return;
self::$stderr=fopen('php://stderr', 'w');
TestController::$buffer=[];
TestController::$num=0;
$t1=new Mytest(0,1,1);
$t1->start();
$t2=new Mytest(0.2,1,2);
$t2->start();
fprintf(self::$stderr, "begin.\n");//flush();
//dd(MyTest::$total_time);
usleep((int)((MyTest::$total_time+0.5)*1e6));
//dd(microtime(true)-MyTest::$microtime,TestController::$buffer);
return Response:://make(str_replace("\n",'<br />',TestController::$buffer));
json(DB::table('test.test')->get());
}
}
class MyTest extends Thread {
public $num;
public static $total_time=0;
public static $microtime=0;
//public static $buffer;
public $t1,$t2,$stderr;
public function __construct($t1,$t2,$num) {
$this->t1=$t1;
$this->t2=$t2;
$this->num=$num;
self::$total_time=(self::$total_time<$this->t1+$this->t2)?$this->t1+$this->t2:self::$total_time;
if (!self::$microtime)
self::$microtime=microtime(true);
}
public function run() {
$this->stderr=fopen('php://stderr', 'w');
$num=$this->num;
//dd(1);
$this->fprintf(STDERR, "%d begin.\n",$num);
try {
$this->fprintf(STDERR, "%d 1.\n", $num);
DB::transaction(function () use ($num){
$this->fprintf(STDERR, "%d 2.\n", $num);
if ($this->t1) usleep((int)($this->t1 * 1e6));
$this->fprintf(STDERR, "%d 3.\n", $num);
DB::select(DB::raw('insert into test.test () values ();'));
$this->fprintf(STDERR, "%d 5.\n", $num);
if ($this->t2) usleep((int)($this->t2 * 1e6));
$this->fprintf(STDERR, "%d 6.\n", $num);
//DB::commit();
});
$this->fprintf(STDERR, "%d success.\n", $num);
} catch (Exception $e){
$this->fprintf(STDERR, "failed %s.\n", $e);
}
}
public function fprintf(...$args){
//echo(sprintf('%0.6f: '.$args[1],microtime(true)-self::$microtime,$args[2]));
fprintf($this->stderr,'%0.6f: '.$args[1],
microtime(true)-self::$microtime,$args[2]);//flush();
}
}
当我调用它时,输出为:
0.009376: 1 begin. 0.009407: 1 1. begin. 0.020410: 2 begin. 0.020451: 2 1.
但是,如果不使用线程,事情就可以正常进行:
$t1=new Mytest(0,1,1);
$t1->run();
$t2=new Mytest(0.2,1,2);
$t2->run();
...
class MyTest/* extends Thread */{
运行良好:
0.000010: 1 begin. 0.000033: 1 1. 0.000650: 1 2. 0.000668: 1 3. 0.001383: 1 5. 1.001610: 1 6. 1.004488: 1 success. 1.004619: 2 begin. 1.004690: 2 1. 1.010701: 2 2. 1.210845: 2 3. 1.215331: 2 5. 2.215501: 2 6. 2.218331: 2 success. begin.
有什么解决方法吗?
顺便说一句,
$ php-zts artisan --version Laravel Framework version 4.2.17