У меня проблема с добавлением нового элемента в массив с указателями.
thread.php:
class Process extends Thread {
public function __construct(&$list )
{
$this->list = $list;
}
public function run() {
while ((1000 <= count($this->list))) {
print_r($list) // array("one", "two");
listing($this->list);
print_r($list) // still array("one", "two");
}
}
}
index.php:
$links = array("one", "two");
function addNew(&$list)
{
// some job
array_push($list, "three");
print_r($list) // array("one", "two","three");
}
function work(&$list)
{
// some code...
addNew($list);
}
$jobs = array(
new Process($list),
new Process($list),
new Process($list)
);
foreach ($jobs as $job)
$job->start();
Значение ссылок будет всегда только («один», «два») независимо от того, как элементы я добавлю позже в функцию addNew()
,
Мне нужны указатели, потому что это будет многократно повторяться с огромным количеством элементов, и я не хочу всегда создавать новый массив.
Причина, по которой вам не разрешено использовать ссылки, даже для типов, которые не требуют сериализации, заключается в том, что не было бы возможности обеспечить безопасность, если бы вам было позволено это делать …
Учтите следующее:
$this->member = $data;
В настоящее время это атомарная запись в объект Threaded, и это:
$data = $this->member;
атомное чтение.
Если эти действия не были атомарными, учтите, что если какой-то другой поток вызывает первый пример кода, в то время как другой поток вызывает второй, $data
в лучшем случае будет мусором, а в худшем — пороком.
Учтите, что если ссылки разрешены и работает следующий код:
$data =& $this->member;
Контекст со ссылкой на данные позволил бы нарушить безопасность, без возможности вмешательства, было бы чрезвычайно трудно программировать потоками таким способом.
Прелесть API высокого уровня в том, что вам не нужно слишком беспокоиться о безопасности, он предоставляется вам, не ищите способов нарушить эту безопасность, это хороший совет.
Все объекты Threaded ведут себя так, как если бы они были массивом, с установленными служебными методами, такими как pop, и операторами, чтобы ваш код мог обрабатывать их как массив.
Потоковые объекты не сериализуются, они безопасны, вы по-прежнему не можете использовать ссылки, но и вам это тоже не нужно:
<?php
class Shared extends Threaded {}
class Appender extends Thread {
public function __construct(Shared $shared) {
$this->shared = $shared;
}
public function run() {
while (count($this->shared) < 1000) {
$this->shared[] =
count($this->shared);
}
}
protected $shared;
}
class Shifter extends Thread {
public function __construct(Shared $shared) {
$this->shared = $shared;
}
public function run() {
while(count($this->shared)) {
var_dump($this->shared->shift());
}
}
}
$shared = new Shared();
$appender = new Appender($shared);
$shifter = new Shifter($shared);
$appender->start();
$shifter->start();
$appender->join();
$shifter->join();
?>
Приведенный выше код разделяет объект класса Shared между двумя другими потоками, в качестве простого примера: один поток безопасно перемещается, а другой — из одного и того же массива.
Этот пример кода не предназначен для того, чтобы быть хорошим примером чего-либо другого, кроме использования потоковых объектов, как если бы они были массивами.
Других решений пока нет …