目錄
常見行程通訊方式
一些理論基礎
system V 信號量
信號量類型
php模擬多進程操作公共資源
使用php封裝system v 信號量集函數
首頁 後端開發 PHP問題 簡單了解php進程通訊之信號量

簡單了解php進程通訊之信號量

Sep 02, 2022 pm 04:57 PM
php

(推薦教學:PHP影片教學

常見行程通訊方式

一些理論基礎

  • 臨界資源:每次僅允許一個行程存取的資源。
  • 臨界區:每個進程中存取臨界資源的那段程式碼叫做臨界區

所謂臨界區(也稱為臨界區段)就是存取和操作共享資料的程式碼段。

進程互斥:兩個或以上的進程不能同時進入關於同一組共享變數的臨界區域,即一個進程正在存取臨界資源,另一個進程要想存取必須等待。

進程同步:主要研究如何確定數個進程之間的執行順序和避免資料競爭的問題即,如何讓多個進程能一塊很好的協作運行

所謂同步,就是並發進程/執行緒在一些關鍵點上可能需要互相等待與互通訊息,這種相互制約的等待與互通訊息稱為進程/執行緒同步。

舉個生活的同步例子,你肚子餓了想要吃飯,你叫媽媽早點做飯,媽媽聽到後就開始做飯,但是在媽媽沒有做完飯之前,你必須阻塞等待,等媽媽做完飯後,自然會通知你,接著你吃飯的事情就可以進行了。

注意,同步與互斥是兩種不同的概念:

同步就好比:「操作A 應在操作B 之前執行」,「操作C 必須在操作A 與操作B都完成之後才能執行」等;

互斥就好比:「操作A 和操作B 不能在同一時刻執行」;

system V 信號量

信號量用途:主要用於多進程或多執行緒對公共資源物件的存取控制。用來解決多進程(多執行緒同步的問題),類似一把鎖,在存取前取得鎖(取得不到則等待),存取後釋放鎖。

多進程/多執行緒一般是並發執行,如果對公共資源存取沒有做同步處理,很容易造成資料破壞

信號量其實是一個整數的計數器,主要用於實現進程間的互斥與同步,而不是用於快取進程間通訊的資料。

信號量表示資源的數量,控制信號量的方式有兩種原子操作:

一個是P 操作,這個操作會把信號量減去-1,相減後如果信號量< 0,則表示資源已被佔用,進程需阻塞等待;相減後如果信號量>= 0,則表示還有資源可使用,進程可正常繼續執行。

另一個是V 操作,這個操作會把信號量加上1,相加後如果信號量<= 0,則表示當前有阻塞中的進程,於是會將該進程喚醒運行;相加後如果信號量> 0,則表示當前沒有阻塞中的進程;

P 操作是用在進入共享資源之前,V 操作是用在離開共享資源之後,這兩個操作是必須成對出現的。

舉個類比,2 個資源的信號量,相當於2 條火車軌道,PV 操作如下圖過程:

一輛火車進入軌道,相當於信號量的P操作,資源-1,這樣就剩下一條軌道

#接著又一輛火車佔用另一條軌道,也就是P操作,資源-1

此時交通號誌燈變為紅色,因為沒有軌道可用,第三輛火車必須等待

第一輛火車離開軌道,相當於V操作,此時軌道資源為1,交通燈變為綠燈

#第三輛火車發現交通號誌變綠,於是進入火車軌道,軌道資源耗盡為0,於是交通號誌燈變成紅燈

在這個火車軌道系統中,軌道是公共資源,每輛火車好比一個線程,交通號誌的就是號誌量的作用。信號量可以實現鎖的互斥操作,也可以實現進程/線程同步

信號量類型

1)二進位信號量(也叫二值信號量)

此時訊號量的初值只能是0和1。 (二進位信號量可以實現互斥鎖操作)

2)一般/計數信號量

此時信號量的初值可以是任意非負數。顯然,其包含二進位信號量。上面舉的火車軌道例子就可以使用計數信號量來實現,一般計數信號量與鎖的區別是它可以允許多個線程/進程(線程的數量由計數信號量初值定義) 同時操作公共資源

一般只有在開發多進程的時候才可能遇到需要使用信號量的場景,phper 幾乎很少有使用信號量的場景,就算有多進程對公共資源操作,大多也是使用flock 文件鎖做互斥操作

php模擬多進程操作公共資源

<?php
$file = "num.txt";//定一个空文件
$count =0;
file_put_contents($file,$count);

$pid = pcntl_fork();//fork 一个进程

if($pid == 0){//子进程执行逻辑
    $x = (int)file_get_contents($file);//读取文件内容
    //i 循环累加
    for($i=0; $i<1000; $i++){
        $x = $x + 1;
    }
    //写入文件
    file_put_contents($file,$x);
    //子进程退出
    exit(0);
}
//父进程执行逻辑
$x = (int)file_get_contents($file);
for($i=0; $i<1000; $i++){
    $x = $x+1;
}
//累加写入
file_put_contents($file,$x);
登入後複製

在寫一個shell 腳本輔助

#!/bin/bash
for a in {1..1000}
do
    (php demo1.php)
    b=`cat num.txt`
    if [ $b != 2000 ]
    then
        echo -e "错误$b"
    fi
done
登入後複製

按理來說,變數$x 最後寫入檔案的值應該是2000,但很不幸,並不是如此,我們對上面的腳本執行一下:

運行了1000次,發現出現了變數$x值結果是1000 的有8次,雖然發生錯誤的機率比較小,但是在計算機裡是不能容忍的。

為什麼會出現這種情況,我們知道單核心cpu系統裡為了實現多個程式同時運行的假象,作業系統通常都採用時間片調度,一個進程時間片用完就切換下一個進程運行,加上我們的高階語言不是每一行程式碼都是原子性的,例如x = (int)file_get_contents($file) 這行程式碼對我們來說是不可分割是原子性的,但是經過編譯器編譯成匯編碼【機器指令】可能是多條指令實現,這樣就會出現問題,如果指令只執行到一半進程分配的時間片用完或者被其他進程打斷,都有可能造成資料損壞,導致最後計算結果出現誤差

使用php封裝system v 信號量集函數

<?php
$file = "num.txt";//定一个空文件
$count =0;
$key = ftok("demo1.php","x");
$sem_id = sem_get($key,1);// 第二个参数是个整数,表示设置信号量集,设置为1 把它当做二值信号量来用,用于互斥
file_put_contents($file,$count);
$pid = pcntl_fork();//fork 一个进程
if($pid == 0){//子进程执行逻辑
sem_acquire($sem_id); // P -1 操作 获取一个信号量 , 如果为0表示资源被占用进程挂起等待信号量释放
    $x = (int)file_get_contents($file);//读取文件内容
    //i 循环累加
    for($i=0; $i<1000; $i++){
        $x = $x + 1;
    }
    //写入文件
    file_put_contents($file,$x);
       sem_release($sem_id); //V +1 操作 释放信号量
    //子进程退出
    exit(0);
}
//父进程执行逻辑
sem_acquire($sem_id); // P -1 操作  获取信号量, 如果为0表示资源被占用进程挂起等待信号量释放
$x = (int)file_get_contents($file);
for($i=0; $i<1000; $i++){
    $x = $x+1;
}
//累加写入
file_put_contents($file,$x);
sem_release($sem_id); //V +1 操作 释放信号量
登入後複製

加入信號量後,那就一定保證100%是2000,絕對不會出現其他數值。

(推薦教學:PHP影片教學

以上是簡單了解php進程通訊之信號量的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

適用於 Ubuntu 和 Debian 的 PHP 8.4 安裝和升級指南 適用於 Ubuntu 和 Debian 的 PHP 8.4 安裝和升級指南 Dec 24, 2024 pm 04:42 PM

PHP 8.4 帶來了多項新功能、安全性改進和效能改進,同時棄用和刪除了大量功能。 本指南介紹如何在 Ubuntu、Debian 或其衍生版本上安裝 PHP 8.4 或升級到 PHP 8.4

我後悔之前不知道的 7 個 PHP 函數 我後悔之前不知道的 7 個 PHP 函數 Nov 13, 2024 am 09:42 AM

如果您是經驗豐富的PHP 開發人員,您可能會感覺您已經在那裡並且已經完成了。操作

如何設定 Visual Studio Code (VS Code) 進行 PHP 開發 如何設定 Visual Studio Code (VS Code) 進行 PHP 開發 Dec 20, 2024 am 11:31 AM

Visual Studio Code,也稱為 VS Code,是一個免費的原始碼編輯器 - 或整合開發環境 (IDE) - 可用於所有主要作業系統。 VS Code 擁有大量針對多種程式語言的擴展,可以輕鬆編寫

在PHP API中說明JSON Web令牌(JWT)及其用例。 在PHP API中說明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

php程序在字符串中計數元音 php程序在字符串中計數元音 Feb 07, 2025 pm 12:12 PM

字符串是由字符組成的序列,包括字母、數字和符號。本教程將學習如何使用不同的方法在PHP中計算給定字符串中元音的數量。英語中的元音是a、e、i、o、u,它們可以是大寫或小寫。 什麼是元音? 元音是代表特定語音的字母字符。英語中共有五個元音,包括大寫和小寫: a, e, i, o, u 示例 1 輸入:字符串 = "Tutorialspoint" 輸出:6 解釋 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。總共有 6 個元

解釋PHP中的晚期靜態綁定(靜態::)。 解釋PHP中的晚期靜態綁定(靜態::)。 Apr 03, 2025 am 12:04 AM

靜態綁定(static::)在PHP中實現晚期靜態綁定(LSB),允許在靜態上下文中引用調用類而非定義類。 1)解析過程在運行時進行,2)在繼承關係中向上查找調用類,3)可能帶來性能開銷。

您如何在PHP中解析和處理HTML/XML? 您如何在PHP中解析和處理HTML/XML? Feb 07, 2025 am 11:57 AM

本教程演示瞭如何使用PHP有效地處理XML文檔。 XML(可擴展的標記語言)是一種用於人類可讀性和機器解析的多功能文本標記語言。它通常用於數據存儲

什麼是PHP魔術方法(__ -construct,__destruct,__call,__get,__ set等)並提供用例? 什麼是PHP魔術方法(__ -construct,__destruct,__call,__get,__ set等)並提供用例? Apr 03, 2025 am 12:03 AM

PHP的魔法方法有哪些? PHP的魔法方法包括:1.\_\_construct,用於初始化對象;2.\_\_destruct,用於清理資源;3.\_\_call,處理不存在的方法調用;4.\_\_get,實現動態屬性訪問;5.\_\_set,實現動態屬性設置。這些方法在特定情況下自動調用,提升代碼的靈活性和效率。

See all articles