Рассмотрим этот код, он довольно понятен:
<?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