Expanded use of PHP pthread and points for attention

Time:2021-9-19

1、 Creation and use of threads

1. Thread class

Basic creation and use:

<?php

//Implement your own thread class myThread by inheriting the thread class

class MyThread extends Thread{

  //Override constructor

  function __construct(){

  }

  //Override the run method (running the tasks that the child thread needs to perform)

  function run(){

  }

}

//Object instantiation and running are just like Java

$mt = new MyThread();

$mt->start();

Of course, as a thread class, there must be other methods for querying thread status and managing threads

<?php

//Gets the parent thread ID of the creation thread

Thread::getCreatorId 

//Get current thread ID

Thread::getCurrentThreadId

//Gets the current thread reference

Thread::getCurrentThread 

//Add thread to detection

Thread::join

//Check whether the thread is detected (whether it is joined)

Thread::isJoined

//Forcibly kill thread

Thread::kill

2. Worker class

The parent class of worker class is thread class, so the basic usage is the same as thread. Compared with the thread class, the worker class adds the function of thread reuse (to reduce the resources consumed in creating and destroying threads), which is usually used in conjunction with the stackable class, that is, the worker class can be used as either a thread or a task container, such as:


<?php

class Task extends Stackable{

  function __construct($no){

    $this->no = $no;

  }

  function run(){

    echo "task{$this->no}:run".PHP_EOL;

  }

}

class MyWork extends Worker{

  function __construct(){

  }

  function run(){

  }

}

$t1= new Task(1);

$t2= new Task(2);

$t3= new Task(3);

$my = new MyWork();

$my->stack($t1);

$my->stack($t2);

$my->start();

$my->stack($t3);

Final output:


task1:run

task2:run

task3:run

Of course, the worker class has other methods for the parent thread to manage it

//Get the number of tasks that have not been executed

Worker::getStacked 

//Judge whether the worker is closed

Worker::isShutdown

//Determine whether the worker is working

Worker::isWorking

//Close destroy worker

Worker::shutdown

//Stack tasks

Worker::stack

//Take the task out of the stack (if there is a problem with this API, use it with caution)

Worker::unstack

2、 Some problems and precautions encountered by PHP threads

1. Hash table (array) operation cannot be performed directly on the properties of thread class, such as:

//This is not valid

$this->var1["hello"] = "world"; 

//Change to

$this->var1 = ["hello"=>"world"];

Why? Because the assignment of thread class attributes is realized through serialization, and its essence is to store serialized data, it does not support the direct operation of hash table (array) commonly used in PHP.

2. The attribute of thread class cannot be “closure function”

Reason: closure function cannot be serialized; Therefore, if you want to use “callback function” in the thread, give up the thread;

3. Thread object opens up the second space of PHP

(1) After the thread is created, it cannot access the variables of the parent thread. For example, $globals or global cannot operate the global variables of the parent thread. This should take into account the problem of thread safety;

(2) However, the parent thread can access the contents of the child thread object;

Extended content

PHP pthread multithreading

Threads, sometimes called lightweight processes, are the smallest unit of program execution. Thread is an entity in a process and the basic unit independently scheduled and dispatched by the system. Thread does not own system resources. It shares all resources owned by the process with other threads belonging to the same process. One thread can create and undo another thread, and multiple threads in the same process can execute concurrently. Every program has at least one thread, that is, the program itself, which is usually called the main thread. Thread is a single sequential control flow in a program. In a single program, running multiple threads to complete different work at the same time is called multithreading.

<?php
 
//Implementing multithreading must inherit the thread class
class test extends Thread {
  public function __construct($arg){
    $this->arg = $arg;
  }
 
  //When the start method is called, the code in the run method of the object will execute asynchronously in a separate thread.
  public function run(){
    if($this->arg){
      printf("Hello %s\n", $this->arg);
    }
  }
}
$thread = new test("World");
 
if($thread->start()) {
  //The join method is used to make the current main thread wait for the thread to finish executing
  //Confirm that the execution of the joined thread ends, which has nothing to do with the thread execution order.
  //That is, when the main thread needs the processing result of the sub thread, the main thread needs to wait for the sub thread to finish executing
  //Get the results of the child thread, and then process the subsequent code.
  $thread->join();
}
?>

Let’s modify the above code to see the effect


<?php
 
class test extends Thread {
  public function __construct($arg){
    $this->arg = $arg;
  }
  public function run(){
    if($this->arg){
      sleep(3);
      printf("Hello %s\n", $this->arg);
    }
  }
}
$thread = new test("World");
 
$thread->start();
 
echo "main thread\r\n";
?>

Instead of calling join, we call the start method directly. The main thread does not wait, but outputs the main thread. The child thread waits 3 seconds before outputting Hello world.