The examples in this article describe the basic usage of PHP semaphores. Share it with everyone for your reference, the details are as follows:
Some theoretical basis:
Semaphore: also known as semaphore, semaphore, used to solve process (thread synchronization problem), similar to a lock, acquire the lock before access (wait if not acquired), release after access Lock.
Critical resources: Resources that only one process is allowed to access at a time.
Critical Section: The code that accesses critical resources in each process is called the critical section
Process mutual exclusion: Two or more processes cannot enter the critical area on the same set of shared variables at the same time, that is, one process is accessing critical resources, and the other process must wait before accessing.
Process synchronizationMainly studies how to determine the execution order between several processes and avoid data competition issues, that is, how to make multiple processes run well together
Example: (from Baidu Encyclopedia)
Take the operation of a parking lot as an example. For simplicity, assume that there are only three parking spaces in the parking lot, and all three parking spaces are empty at the beginning. At this time, if five cars come at the same time, the gatekeeper will allow three of them to enter directly, and then put down the car block. The remaining cars must wait at the entrance, and subsequent cars will also have to wait at the entrance. At this time, a car left the parking lot. After the gatekeeper learned about it, he opened the car barrier and put the car in. If two more cars left, he could put in two more cars, and so on.
In this parking lot system, parking spaces are public resources. Each car is like a thread, and the gatekeeper acts as a semaphore.
$key=ftok(__FILE__,'t'); /** * 获取一个信号量资源 int $key [, int $max_acquire = 1 [, int $perm = 0666 [, int $auto_release = 1 ]]] $max_acquire:最多可以多少个进程同时获取信号 $perm:权限 默认 0666 $auto_release:是否自动释放信号量 */ $sem_id=sem_get($key); #获取信号 sem_acquire($seg_id); //do something 这里是一个原子性操作 //释放信号量 sem_release($seg_id); //把次信号从系统中移除 sem_remove($sem_id); //可能出现的问题 $fp = sem_get(fileinode(__DIR__), 100); sem_acquire($fp); $fp2 = sem_get(fileinode(__DIR__), 1)); sem_acquire($fp2);
Implementation of a read-write semaphore in PHP:
class rw_semaphore { const READ_ACCESS = 0; const WRITE_ACCESS = 1; /** * @access private * @var resource - mutex semaphore */ private $mutex; /** * @access private * @var resource - read/write semaphore */ private $resource; /** * @access private * @var int */ private $writers = 0; /** * @access private * @var int */ private $readers = 0; /** * Default constructor * * Initialize the read/write semaphore */ public function __construct() { $mutex_key = ftok('/home/cyrus/development/php/sysvipc/rw_semaphore.php', 'm'); $resource_key = ftok('/home/cyrus/development/php/sysvipc/rw_semaphore.php', 'r'); $this->mutex = sem_get($mutex_key, 1); $this->resource = sem_get($resource_key, 1); } /** * Destructor * * Remove the read/write semaphore */ public function __destruct() { sem_remove($this->mutex); sem_remove($this->resource); } /** * Request acess to the resource * * @param int $mode * @return void */ private function request_access($access_type = self::READ_ACCESS) { if ($access_type == self::WRITE_ACCESS) { sem_acquire($this->mutex); /* update the writers counter */ $this->writers++; sem_release($this->mutex); sem_acquire($this->resource); } else { sem_acquire($this->mutex); if ($this->writers > 0 || $this->readers == 0) { sem_release($this->mutex); sem_acquire($this->resource); sem_acquire($this->mutex); } /* update the readers counter */ $this->readers++; sem_release($this->mutex); } } private function request_release($access_type = self::READ_ACCESS) { if ($access_type == self::WRITE_ACCESS) { sem_acquire($this->mutex); /* update the writers counter */ $this->writers--; sem_release($this->mutex); sem_release($this->resource); } else { sem_acquire($this->mutex); /* update the readers counter */ $this->readers--; if ($this->readers == 0) sem_release($this->resource); sem_release($this->mutex); } } /** * Request read access to the resource * * @return void */ public function read_access() { $this->request_access(self::READ_ACCESS); } /** * Release read access to the resource * * @return void */ public function read_release() { $this->request_release(self::READ_ACCESS); } /** * Request write access to the resource * * @return void */ public function write_access() { $this->request_access(self::WRITE_ACCESS); } /** * Release write access to the resource * * @return void */ public function write_release() { $this->request_release(self::WRITE_ACCESS); } }
Shared memory signals implement atomic operations
$SHM_KEY = ftok("/home/joeldg/homeymail/shmtest.php", 'R'); $shmid = sem_get($SHM_KEY, 1024, 0644 | IPC_CREAT); $data = shm_attach($shmid, 1024); // we now have our shm segment // lets place a variable in there shm_put_var ($data, $inmem, "test"); // now lets get it back. we could be in a forked process and still have // access to this variable. printf("shared contents: %s\n", shm_get_var($data, $inmem)); shm_detach($data);
The above examples are from the php manual sem_get function comment
Readers who are interested in more PHP-related content can check out the special topics of this site: "Introduction Tutorial on PHP Basic Syntax", "Summary of PHP Error and Exception Handling Methods", "Summary of PHP Programming Algorithms" and "php Object-Oriented Programming" Design introductory tutorial》
I hope this article will be helpful to everyone in PHP programming.