PHP Mutex  screenshot

PHP Mutex

Content

PHP Mutex

The pthreads extension gives us the full package of POSIX threads features. While some might find the use of plain threads and the basic workflow control they offer out of the box, others might need to venture further into the world of threading. This time we will be discussing mutexes. Mutexes, having nothing to do with muting, come from the term “mutual exclusion”. In a threaded php script, you will often have to watch out for the timing and sequence of the execution of each instruction you give so things don’t go wrong. When different processes finish their execution in a chaotic manner which also affects the outcome negatively, we observe what is called “race condition”. Race condition originates from the early days of computing where mistakes in circuitry design would often leave two signals racing to influence the output which made it non reliable. Mutexes are used so no two concurrently running tasks, especially when using the same resources, will end up racing each other.

Think of it in this way - often at work meetings, the team of developers will sit around a table and discuss ideas. However, if all of them start talking at the same time or start talking while someone else is, nothing productive will come out of the whole discussion. The same happens when someone has to explain and map out their idea when it depends on the idea of someone else who hasn’t spoken yet. As the leader of a team, what you can do is have an object to pass to each speaker. Imagine a teddy bear. Whoever holds the teddy bear can speak. Once they are done, they leave the teddy bear on the table and the next appointed speaker comes in possession of it. In the world of threading the teddy bear is the Mutex object. Holding the teddy bear translates as locking the mutex, so nobody else can claim it. Letting go of it translates to unlocking a mutex. If the moderator of the meeting wishes to have everyone be able to work simultaneously with the others, he can wish to put away the teddy bear and leave everyone to their work. This translates to destroying a mutex.

Below you can see a simple way in which mutexes can be applied. Using our previous “train simulation” you can see how mutexes affect the flow of execution.

<?php
class PhpThread extends Thread {
    public function __construct($arg) {
        $this->arg = $arg;
    }
    public function run() {
        //Initialization mutex
        $mutex = Mutex::create();
        if ($this->arg) {
            Mutex::lock($mutex);
            $sleep = mt_rand(1, 15);
            printf(Train % shasdeparted, itwilltravelfor % dseconds’ . "\n", $this->arg, $sleep);
            sleep($sleep);
            printf('Train %s  has arrived' . "\n", $this->arg);
            Mutex::unlock($mutex);
        }
    }
}
// Creating the stack array which will hold our “trains”
$stackArray = array();
//Initiating the threads
foreach (range("0", "3") as $i) {
    $stackArray[] = new PhpThread($i);
}
// Execute each thread.
foreach ($stackArray as $thread) {
    $thread->start();
}
?>

Which will output:

Train 1 has departed; it will travel for 11 seconds

Train 1 has arrived

Train 2 has departed; it will travel for 12 seconds

Train 2 has arrived

Train 3 has departed; it will travel for 10 seconds

Train 3 has arrived

You can clearly see that this time, instead of all trains leaving the station together, each train waits for a green light - the unlocked mutex. While this is a very simple example, mutexes can have a wide variety of uses in real world examples such as accessing the same resource from a database or any task of which only one instance should be run at a time.