Intereting Posts
«Потерянное соединение с сервером MySQL» при попытке подключения к удаленному серверу MySQL Получить все фотографии из Instagram, которые имеют определенный хэштегов с PHP json_encode () возвращает false Как использовать php restful api-centric design internal вместо HTTP-запроса передача переменной размерной формы Путаница с параметрами.yml и config_ (dev | stage | prod) .yml для соединений с базой данных Как добавить возможности Ajax для Symfony отправлять электронную почту и вставлять данные в базу данных php mysql Symfony2 – Невозможно назначить роли для пользователя (массив ролей пуст) Рассчитать годы с даты Можно ли автоматически преобразовать Java-код в PHP? Ошибка «Неожиданный T_OBJECT_OPERATOR» в PHP Настройка установки PHP: ошибка: не удается найти php_pdo_driver.h Преобразование текста (с разделителем табуляции) в ассоциативный массив PHP вместо этого кода для CSV? Как я могу убедиться, что lastInsertId () не относится к другой одновременной вставке?

Класс PHP / pthreads Thread не может использовать массив?

Я нашел PECL pthread Thread не может использовать объект массива. Что я могу сделать, чтобы найти причину?

Пример кода:

  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(); } 

Проблема

PHP – это среда без общего доступа: это означает, что каждый процесс (или поток) должен иметь свою собственную копию интерпретатора, всех модулей и кода пользователя.

Структура HashTable которая не только поддерживает массивы PHP, но используется во всей базе PHP-кода, никогда не предназначалась для управления несколькими контекстами.

Менеджер памяти, который будет вызываться всякий раз, когда вы устанавливаете новый член массива (эквивалент malloc), unset one (эквивалент бесплатного) или обновляете один (эквивалент free then malloc), является неотъемлемой частью общего ничего архитектура и, кроме всего прочего, специально предназначена для того, чтобы запретить любой контекст свободной памяти, который был выделен другим контекстом, поскольку это является нарушением общего ничего.

Виртуальная машина предполагает, что это единственный контекст, манипулирующий массивом.

Все добавочные коды делают одно и то же предположение.

Последствия для игнорирования правил – ничего не разделяйте – ужасны: вы разбиваете PHP.

Все это позволяет вам хранить и манипулировать фактическим массивом в нескольких контекстах нереализуемым, и сделать его нежелательным.

PHP5

Массивы будут сериализованы после установки их в качестве элемента Threaded .

Вы должны заменить использование массивов объектами Threaded .

Объект Threaded можно манипулировать так, как если бы он был массивом.

Вот что вам нужно начать:

 <?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) вводит понятия автоматической неизменности для Threaded объектов.

Цитата из моего сообщения в блоге о неизменности в pthreads v3:

В pthreads v3, устанавливая элемент объекта Threaded ( A ) на другой объект Threaded ( B ), делает ссылку, что A сохраняет значение B неизменяемым.

Неизменность – это оптимизация производительности.

Очевидно, что большинство случаев использования массивов включают в себя мутирование массива, которые теперь не всегда могут поддерживать Threaded объекты.

В этом конкретном случае ни один из элементов массива Threaded является Threaded .

pthreads v3 (PHP7) представляет концепцию Volatile объектов.

Летучие , Прилагательные : могут быстро и непредсказуемо меняться, особенно в худшую сторону.

Volatile объекты медленнее, чем объекты Threaded потому что они не могут извлечь выгоду из оптимизации производительности, которую позволяет сделать неизменность.

Volatile объекты служат хорошей альтернативой массивам в pthreads v3. pthreads будет принудительно использовать массивы для объектов Volatile когда они будут установлены как элементы Threaded objects:

 <?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(); ?> 

Будет давать:

 array(2) { [0]=> string(5) "Hello" [1]=> string(5) "World" } object(Volatile)#2 (2) { [0]=> string(5) "Hello" [1]=> string(5) "World" } 

Это заставляет $this->array вести себя так, как ожидалось, во время выполнения Thread .

Существует побочный эффект, проиллюстрированный выходом следующего кода:

 <?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); ?> 

Будет давать:

 object(Volatile)#2 (2) { [0]=> string(5) "Hello" [1]=> string(5) "World" } array(2) { [0]=> string(5) "Hello" [1]=> string(5) "World" } 

Обратите внимание, что объект Volatile в Thread отключен от array который был предоставлен его конструктору, так что основной контекст все еще манипулирует array .

Автоматическое принуждение служит для уменьшения скорости wtfs-per-minute, когда Thread управляет массивом, который был передан из другого источника.

Всегда лучше быть явным; Не полагаться на принуждение – лучший вариант.

Если вы уже знаете, что некоторые зависимости будут массивами, тогда с этим справитесь, прежде чем устанавливать их как членов, полностью избегая принуждения.

Можно избежать автоматического принуждения к Volatile с помощью явного приведения:

 <?php class Test extends Thread { public function run() { $this->result = (array) [ "Hello" => "World" ]; } } $test = new Test(); $test->start() && $test->join(); var_dump($test->result); ?> 

Будет давать

 array(1) { ["Hello"]=> string(5) "World" } 

Как показывает пример кода, это полезно, когда вы действительно хотите использовать массив для хранения результата. Как и в случае с PHP5, массив будет сериализован для хранения.