que - pthreads php install
Una clase de subproceso PHP/pthreads no puede usar matriz? (1)
El problema
PHP es un entorno de nada compartido: Esto significa que cada proceso (o subproceso) debe tener su propia copia del intérprete, todos los módulos y el código de usuario.
La estructura HashTable
que no solo admite matrices PHP, sino que se utiliza en toda la base de código PHP, nunca fue pensada para ser manipulada por múltiples contextos.
El administrador de memoria, que se invocará siempre que establezca un nuevo miembro de una matriz (equivalente de malloc), desarme uno (equivalente de libre) o actualice uno (equivalente de libre y luego malloc), es una parte integral de la nada compartida la arquitectura, y entre otras cosas, está específicamente diseñada para desautorizar cualquier contexto para liberar memoria asignada por otro contexto, ya que esto constituye una violación de la nada compartida.
La máquina virtual asume que es el único contexto que manipula una matriz.
Todo el código de extensión hace la misma suposición.
Las consecuencias por ignorar las reglas, no compartir nada, son terribles: bloqueas PHP.
Todo esto permite que almacenar y manipular una matriz real en contextos múltiples sea irrealizable, y debería hacerlo indeseable.
PHP5
Las matrices se serializarán al configurarlas como miembro de un objeto con Threaded
.
Debe reemplazar el uso de matrices con objetos con Threaded
.
Un objeto con Threaded
se puede manipular como si fuera una matriz.
Aquí hay algo para que comiences:
<?php
class Test extends Thread {
public function __construct(Threaded $storage) {
$this->storage = $storage;
}
public function run(){
$i = 0;
while(++$i < 10) {
$this->storage[]=rand(0,1000);
}
$this->synchronized(function($thread){
$thread->stored = true;
$thread->notify();
}, $this);
}
}
$storage = new Threaded();
$my = new Test($storage);
$my->start();
$my->synchronized(function(Thread $thread){
while (!$thread->stored) {
$thread->wait();
}
}, $my);
var_dump($storage);
?>
PHP7
pthreads v3 (PHP7) introduce los conceptos de inmutabilidad automática para objetos con Threaded
.
Cita de mi blog sobre la inmutabilidad en pthreads v3:
En pthreads v3, establecer un miembro de un objeto
Threaded
( A ) en otro objetoThreaded
( B ) hace que la referencia que A tiene para B sea inmutable.
La inmutabilidad es una optimización del rendimiento.
Obviamente, la mayoría de los casos de uso para las matrices implican la mutación de la matriz, que ahora los objetos de Threaded
no siempre son compatibles.
En este caso particular, ninguno de los miembros de la matriz de Threaded
está Threaded
.
pthreads v3 (PHP7) introduce el concepto de objetos Volatile
.
Volátil , Adjetivo : Es probable que cambie rápidamente e impredeciblemente, especialmente para lo peor.
Volatile
objetos Volatile
son más lentos que los objetos con Threaded
porque no pueden beneficiarse de las optimizaciones de rendimiento que la inmutabilidad nos permite.
Volatile
objetos Volatile
sirven como una buena alternativa a las matrices en pthreads v3. pthreads forzará matrices a objetos Volatile
cuando se establecen como miembros de objetos con Threaded
:
<?php
class Test extends Thread {
public function run(){
$array = [
"Hello",
"World"
];
var_dump($array);
$this->array = $array;
var_dump($this->array);
}
}
$test = new Test();
$test->start() && $test->join();
?>
Rendirá:
array(2) {
[0]=>
string(5) "Hello"
[1]=>
string(5) "World"
}
object(Volatile)#2 (2) {
[0]=>
string(5) "Hello"
[1]=>
string(5) "World"
}
Esto hace que $this->array
comporte como se esperaba durante el tiempo de ejecución del Thread
.
Hay un efecto secundario, ilustrado por el resultado del siguiente código:
<?php
class Test extends Thread {
public function __construct(array $array) {
$this->array = $array;
}
public function run(){
var_dump($this->array);
}
}
$array = [
"Hello",
"World"
];
$test = new Test($array);
$test->start() && $test->join();
var_dump($array);
?>
Rendirá:
object(Volatile)#2 (2) {
[0]=>
string(5) "Hello"
[1]=>
string(5) "World"
}
array(2) {
[0]=>
string(5) "Hello"
[1]=>
string(5) "World"
}
Tenga en cuenta que el objeto Volatile
en el Thread
está desconectado de la array
que se suministró a su constructor, por lo que el contexto principal todavía está manipulando una array
.
La coerción automática sirve para reducir la tasa de wtfs por minuto cuando un Thread
manipula una matriz que se pasó desde otra fuente.
Siempre es mejor ser explícito; No depender de la coacción es la mejor opción.
Si ya sabe que algunas dependencias serán matrices, entonces trátelas antes de establecerlas como miembros, evitando la coerción por completo.
Es posible evitar la coacción automática a Volatile
mediante el uso de un lanzamiento explícito:
<?php
class Test extends Thread {
public function run() {
$this->result = (array) [
"Hello" => "World"
];
}
}
$test = new Test();
$test->start() && $test->join();
var_dump($test->result);
?>
Rendirá
array(1) {
["Hello"]=>
string(5) "World"
}
Como muestra el código de ejemplo, esto es útil cuando realmente desea usar una matriz para almacenar un resultado. Al igual que con PHP5, la matriz se serializará para su almacenamiento.
He encontrado un Thread
pthread PECL no puede usar un objeto de matriz. ¿Qué puedo hacer para encontrar la causa?
Ejemplo de código:
class my extends Thread {
public function __construct() {
$this->arr = array();
$this->id = 0;
}
pulbic function run() {
while (true) {
$this->wait();
}
}
public function set() {
$this->id = rand(0, 1000);
$this->arr[] = rand(0, 1000);
var_dump($this->id);//this is rand
var_dump($this->arr);//this is empty array()
$this->notify();
}
}
$my = new my();
$my->start();
while (true) {
sleep(1);
$my->add();
}