English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Since it is not certain which process will execute first among the processes, it depends on the complex process scheduling algorithm of the kernel. As a result, multiple processes may access the shared memory at the same time, causing unpredictable errors. The name 'semaphore' is quite mysterious, but its English meaning is very easy to understand.
semaphore 英[ˈseməfɔ:(r)] vt. Send a signal, signal with flags;
Similar to the role of a commander.
Let's take a look at the next pseudo-code example of semaphore usage.
1Create a unique identifier for the semaphore
$ftok = ftok(__FILE__, 'a');
2Create semaphore resource ID
$sem_resouce_id = sem_get($ftok);
3Acquire the semaphore
sem_acquire($sem_resource_id);
4Release the semaphore
sem_release($sem_resource_id);
5Destroy the semaphore
sem_remove($sem_resource_id);
Let's take an impolite example to make it easy to understand the use of semaphores in daily life. After understanding, we can apply it to our programming field.
There is only one toilet in a company. When someone uses the toilet, they need to acquire a lock (semaphore) to indicate that the toilet is in use. The code is as follows:
sem_acquire($sem_resource_id);
After the staff finish using the toilet, they need to open the lock and release the lock (semaphore) to indicate that others can now use it. The code is as follows:
sem_release($sem_resource_id);
With a simple lock, we can know whether the current toilet (shared memory) is available. This example is not tasteful, but it illustrates the problem. This blog is also a smelly blog, it's not easy to write... Here is the example code:
<?php //Create a shared memory area $shm_key = ftok(__FILE__, 'a'); $shm_id = shm_attach($shm_key, 1024, 0755); //var_dump($shm_id);die(); resource(4of type (sysvshm) const SHARE_KEY = 1; $child_list = []; //Join the semaphore $sem_id = ftok(__FILE__, 'b'); $signal = sem_get($sem_id); //$signal resource(5of type (sysvsem) ; $i 3$pid = pcntl_fork();++) { if ($pid == exit("Fork fail!".PHP_EOL); -1) { elseif ($pid == 0) { } //Acquire semaphore sem_acquire($signal); if (shm_has_var($shm_id,SHARE_KEY)) { $count = shm_get_var($shm_id, SHARE_KEY); $count++; //Simulate business processing $sec = rand(1, 3); sleep($sec); shm_put_var($shm_id, SHARE_KEY, $count); } $count = 0; $sec = rand(1, 3); sleep($sec); shm_put_var($shm_id, SHARE_KEY, $count); } echo "child process: ".getmypid()." is writing! now count is: $count ".PHP_EOL; //Release semaphore sem_release($signal); exit("child process".getmypid()."end".PHP_EOL); } $child_list[] = $pid; } } while (count($child_list) > 0) { foreach ($child_list as $key => $pid) { $status = pcntl_waitpid($pid, $status); if ($status > 0 || $status == -1) { unset($child_list[$key]); } } sleep(1); } $count = shm_get_var($shm_id, SHARE_KEY); echo " $count ".PHP_EOL; //Destroy semaphore sem_remove($signal); shm_remove($shm_id); shm_detach($shm_id);