Я запускаю программу CGI в не-поточном PHP, немного упражнении в искусственной жизни и эволюции. Организмы имеют геном и интерпретатор, что заставляет их выполнять определенные операции, в том числе перемещаться и взаимодействовать друг с другом на общей карте мира. В настоящее время я поддерживаю плохое видимость потоков, используя несколько процессов PHP, взаимодействующих через базу данных MySQL, но я хочу переписать код так, чтобы он использовал pthreads для непрерывного запуска в одном потоке, не обязательно используя базу данных (хотя я ' d, вероятно, хотите сохранить его для отчетности).PHP: поточные агенты, совместно использующие общий объект
Я просматривал вопросы и отвечал на вопросы и примеры кода на github, но не смог найти ничего, что, насколько я могу судить, касается того, что я хочу. Поскольку я не совсем гениальный OOP-кодер и совершенно новичок в написании многопоточного кода, особенно в PHP, мои вопросы будут довольно широкими.
Я попытался немного сузить круг моих вопросов, написав код, показывающий, что я пытаюсь сделать, но он все еще может быть слишком широким. Я был бы признателен за любые советы о том, как сузить его дальше.
Мои вопросы о коде ниже:
- Как получить Организма действовать на общий объект World, чтобы изменения в объекте Всемирного сообщаются всем потокам, избегая конфликтов и поддержания согласованности?
- Учитывая, что численность населения в конечном счете переменная, есть способ сделать ссылки на части Организмов объекта Всемирного (т.е.. $ Миро-> организмы), и имеют World быть в состоянии создать новый Организмы, как показано ниже (ошибочный) код?
- Учитывая, что я в конечном итоге хочу создать совокупность сотен Организмов, есть ли у вас какие-либо указатели на ограничение количества активных потоков (т. Е. Ограничение использования памяти/процессора), сохраняя при этом постоянство?
Ниже кода (не работает, конечно, но) иллюстрирует то, что я стремлюсь достичь:
/*
* Shared object containing a map of the world and
* methods for getting/setting coordinates
*/
class World extends Thread
{
public $map;
public $sx;
public $sy;
public $organisms;
// set all map coords to 0
public function __construct($sx, $sy, $p)
{
$map = array();
for($i = 0; $i < $sx; $i++)
{
$map[$i] = array();
for($j = 0; $j < $sy; $j++)
{
$map[$i][$j] = 0;
}
}
$this->map = $map;
$this->sx = $sx;
$this->sy = $sy;
// create and start organism threads
$this->organisms = array();
for($i = 0; $i < $p; $i++)
{
// this won't work because threaded objects created
// within a thread scope that have no external references
// are destroyed in the constructor
$this->makeOrganism($i+1, $i+1, $i+1);
}
}
// produces a new organism, adds to world population
public function makeOrganism($x, $y, $value)
{
if($x < 1 || $x > $this->sx) return false;
if($y < 1 || $y > $this->sy) return false;
if($this->getMap($x, $y) != 0) return false;
echo "creating new organism $value\n";
$organisms = $this->organisms;
// doesn't work because the world data is decoupled in the new thread
$organisms[] = new Organism($this, $x, $y, $value);
$this->organisms = $organisms;
return true;
}
// assumes valid coords
public function setMap($x, $y, $value)
{
return $this->map[$x-1][$y-1] = $value;
}
// assumes valid coords
public function getMap($x, $y)
{
return $this->map[$x-1][$y-1];
}
public function getSX()
{
return $this->sx;
}
public function getSY()
{
return $this->sy;
}
public function run()
{
for($i = 0; $i < count($this->organisms); $i++)
{
echo "starting organism ", $this->value, "\n";
$this->organisms[$i]->start();
}
}
}
/*
* Autonomously running agent accessing shared World map
*/
class Organism extends Thread
{
public $value;
public $world;
public $x;
public $y;
public function __construct(World $world, $x, $y, $value)
{
$this->world = $world;
$this->value = $value;
$this->x = $x;
$this->y = $y;
// assume coordinates are empty
$this->world->setMap($x, $y, $value);
}
// try to move organism by $dx, $dy
public function move($dx, $dy)
{
$x = $this->x + $dx;
$y = $this->y + $dy;
if($x < 1 || $x > $this->world->getSX()) return false;
if($y < 1 || $y > $this->world->getSY()) return false;
if($this->world->getMap($x, $y) != 0) return false;
$this->world->setMap($x, $y, $this->value);
$this->world->setMap($this->x, $this->y, 0);
$this->x = $x;
$this->y = $y;
return true;
}
public function getValue()
{
return $this->value;
}
public function run()
{
// infinite loop; organisms move randomly about until they die
while(true)
{
echo "running organism ", $this->getValue(), "\n";
// this should operate on the shared object World,
// maintaining consistency and avoiding conflicts between threads
$dx = rand(-1, 1);
$dy = rand(-1, 1);
$this->move($dx, $dy);
// occasionally add an organism to the population by cloning this one
if(rand(0, 100) > 95)
{
$this->world->makeOrganism($this->x+1, $this->y+1, $this->value+100);
}
// wait random interval, organisms are
// not expected to move all at the same time
$this->wait(1000 + rand(500, 1500));
}
}
}
// initialize shared object
$world = new World(50, 50, 50);
$world->start();
$world->join();
Спасибо за ответ, несмотря на неопределенность вопроса, это большая помощь. Мне нужно выяснить, как создавать PHP7 + pthreads, но это не должно быть слишком сложным. Все, что мне нужно сделать, это выяснить, как заставить любого члена $ организмов дать команду основному потоку объединить новые элементы очереди, такие как _OrganismSpawnTask ($ world, $ organic) _ или что-нибудь еще, что означает взаимодействие между организмами и окружающей средой. Пойду, прочитайте SOLID, попробуйте код и возвращайтесь с более конкретными вопросами, когда я снова застрял. Благодаря! – Gralgrathor
Вы не можете делиться Бассейнами. У каждого Работника может быть собственный пул ... маленький был бы целесообразным ... –
Я думаю (не очень ясно, заметьте, я только на полпути к рядам мастеров дяди Боба), возможно, механизм массового обслуживания с использованием базы данных или простого массива может использоваться для указания основного потока для выполнения конкретной задачи для определенного набора организмов. Таким образом, нет прямого нарушения направленности. Проблема в том, что я пытаюсь имитировать беспорядок реального мира с его хаотическими зависимостями в среде, более подходящей для строгих иерархий. Я не совсем уверен, как правильно настроить свой образ мышления. – Gralgrathor