信号量

sysvsem 扩展

/proc/sysvipc/

一条高级语言指令在底层对应多条机器指令,所有对于一条高级指令来说,并不是原子态的运行,当多个进程/线程对同一资源进行读写时,如果没有做数据同步,很容易造成数据损坏

在c++中使用互斥锁,条件变量,信号量解决.

在linux中PHP使用 systemV 信号量处理

系统调用 semget semctl semop

信号量分类

  1. 二值信号量 binary semaphore 值为0和1,可以通过相关函数修改它的值,这种操作成为PV原语

    P就是减1操作(当前值如果不是1,进程会阻塞,表示当前资源该进程不可访问)

    V就是加1操作(当前值是0可以加1操作,同时会释放当前的资源,让其他进程有机会执行P,就有机会访问公共资源)

  2. 计数信号量 : 计算器,它的值从0到某个最大值

  3. 计算信号量集 : 我们可以认为是个数组,包含计数信号量, systemV 信号量就是计算信号量集

https://www.php.net/manual/zh/function.sem-get.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
$file = "demo1.txt";
$count = 0;
file_put_contents($file, $count);
$key = ftok($file, "x");
$sem_id = sem_get($key,1); // 当做二值信号量来用
$pid = pcntl_fork();

if ($pid == 0) {
    for ($i = 0; $i < 10; $i++) {
        sem_acquire($sem_id);
        $x = (int)file_get_contents($file);
        $x += 1;
        file_put_contents($file, $x);
        sem_release($sem_id);

    }
    exit(0);
}
for ($i = 0; $i < 10; $i++) {
    sem_acquire($sem_id);
    $x = (int)file_get_contents($file);
    $x += 1;
    file_put_contents($file, $x);
    sem_release($sem_id);
}
sem_acquire($sem_id);
echo file_get_contents($file);
sem_release($sem_id);
sem_remove($sem_id);