Автор оригинала: David Wong.
В этой статье описывается использование рабочего и пула в PHP pthreads v3 . Подробности заключаются в следующем:
Некоторые люди подумают, очевидно, что использование потока уже может хорошо работать, почему вы хотите создать работника и пул?
Причина, по которой нам нужно использовать работника и пул, заключается в эффективности, потому что системе дороже создавать новый поток, и каждый созданный поток будет копировать весь контекст текущего выполнения.
Повторное использование потоков в максимально возможной степени может сделать нашу программу более эффективной.
Простой пример рабочего:
php //Create a custom work class and give work a name for easy viewing class Work extends Worker { private $name; public function __construct($name) { $this->name = $name; } public function getName() { return $this->name; } } class Task extends Thread { private $num; public function __construct($num) { $this->num = $num; } public function run() { //Calculate the cumulative sum $total = 0; for ($i = 0; $i < $this->num; $i++) { $total += $i; } echo "work : {$this->worker->getName()} task : {$total} \n"; sleep(1); } } //Create a worker thread $work = new Work('a'); $work->start(); for ($i = 1; $i <= 10; $i++) { //Push task object into worker thread //At this time, the task object can use the worker thread context (variables, functions, etc.) $work->stack(new Task($i)); } //The cleaning task of the loop will block the main thread until all the tasks in the stack are finished while ($work->collect()) ; //Close worker $work->shutdown();
Когда выполняется приведенный выше код, результат вычисления будет выводиться каждую секунду, то есть в рабочем потоке выполняется 10 объектов задачи.
Если 10 объектов задач выполняются отдельно в отдельном пространстве, функция sleep() не будет работать, и их соответствующий режим сна не повлияет на другие потоки.
Измените приведенный выше код:
name = $name;
}
public function getName()
{
return $this->name;
}
}
class Task extends Thread
{
private $num;
public function __construct($num)
{
$this->num = $num;
}
public function run()
{
//Calculate the cumulative sum
$total = 0;
for ($i = 0; $i < $this->num; $i++) {
$total += $i;
}
echo "work : {$this->worker->getName()} task : {$total} \n";
sleep(1);
}
}
//Create two worker threads
$work1 = new Work('a');
$work2 = new Work('b');
$work1->start();
$work2->start();
for ($i = 1; $i <= 10; $i++) {
if ($i <= 5) {
$work1->stack(new Task($i));
} else {
$work2->stack(new Task($i));
}
}
//The cleaning task of the loop will block the main thread until all the tasks in the stack are finished
while ($work1->collect() || $work2->collect()) ;
//Close worker
$work1->shutdown();
$work2->shutdown();Здесь мы создаем два рабочих потока, чтобы объединить 10 объектов задач в два рабочих.
В это время вы можете видеть, что результаты расчета соответствуют один к одному, что указывает на то, что 10 объектов задач выполняются в двух рабочих потоках.
Что касается того, сколько рабочих потоков и объектов задач необходимо создать, это зависит от ваших собственных требований.
Еще одним преимуществом worker является то, что он может повторно использовать объекты и методы в worker. Мы можем создать объект базы данных соединений в работнике, чтобы облегчить вызов каждой задачи.
id = $id;
}
public function run()
{
//Get the database connection in worker
$db = $this->worker->getDb();
$ret = $db->query("select * from tb_user where id = {$this->id}");
$this->result = $ret->fetch(PDO::FETCH_ASSOC);
//Accessing the member variable MSG in worker
echo "data : {$this->result['id']} {$this->result['name']} \t worker data : {$this->worker->msg} \n";
}
}
//Create a worker thread
$work = new DB();
$work->start();
for ($i = 1; $i <= 5; $i++) {
$work->stack(new Task($i));
}
//The cleaning task of the loop will block the main thread until all the tasks in the stack are finished
while ($work->collect()) ;
//Close worker
$work->shutdown();tb_ Вы можете создать пользовательскую таблицу по своему желанию. Я создаю здесь поля идентификатора и имени только для демонстрации
Результаты заключаются в следующем
Если рабочие повторно используют потоки, пул-это более высокая абстракция для рабочих, которая может управлять несколькими рабочими одновременно.
synchronized(function () {
++$this->id;
});
return $this->id;
}
}
class Work extends Worker
{
private $id;
public function __construct(Id $obj)
{
$this->id = $obj->getId();
}
public function getId()
{
return $this->id;
}
}
class Task extends Thread
{
private $num = 0;
public function __construct($num)
{
$this->num = $num;
}
//Calculate the cumulative sum
public function run()
{
$total = 0;
for ($i = 0; $i < $this->num; $i++) {
$total += $i;
}
echo "work id : {$this->worker->getId()} task : {$total} \n";
}
}
//Create a pool to hold three work objects
$pool = new Pool(3, 'Work', [new Id()]);
//Circularly submit 20 task threads to the work object in the pool to run
for ($i = 1; $i <= 20; $i++) {
$pool->submit(new Task($i));
}
//The cleaning task of the loop will block the main thread until the task is finished
while ($pool->collect()) ;
//Close pool
$pool->shutdown();Результаты заключаются в следующем
Для получения дополнительной информации о PHP читатели, интересующиеся этим сайтом, могут ознакомиться со следующими темами: краткое описание навыков работы с процессами и потоками PHP, краткое описание навыков сетевого программирования PHP, вводный курс базового синтаксиса PHP, полная коллекция навыков работы с массивами PHP, краткое описание использования строк PHP “Руководство по работе с базой данных PHP + MySQL” и “Краткое описание навыков работы с общей базой данных PHP”.
Я надеюсь, что эта статья полезна для программирования на PHP.
Оригинал: “https://developpaper.com/examples-of-using-worker-and-pool-in-php-pthreads-v3/”