亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

php進程通信之信號量的作用是什么

發布時間:2022-08-30 10:19:49 來源:億速云 閱讀:88 作者:iii 欄目:開發技術

本篇內容介紹了“php進程通信之信號量的作用是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

    常見進程通信方式

    一些理論基礎

    • 臨界資源:每次僅允許一個進程訪問的資源。

    • 臨界區:每個進程中訪問臨界資源的那段代碼叫臨界區

    所謂臨界區(也稱為臨界段)就是訪問和操作共享數據的代碼段。

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

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

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

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

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

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

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

    system V 信號量

    信號量用途:主要用于多進程或多線程對公共資源對象的訪問控制。 用來解決多進程(多線程同步的問題),類似于一把鎖,訪問前獲取鎖(獲取不到則等待),訪問后釋放鎖。

    多進程/多線程一般是并發執行,如果對公共資源訪問沒有做同步處理,很容易造成數據破壞

    信號量其實是一個整型的計數器,主要用于實現進程間的互斥與同步,而不是用于緩存進程間通信的數據。

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

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

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

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

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

    php進程通信之信號量的作用是什么

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

    php進程通信之信號量的作用是什么

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

    php進程通信之信號量的作用是什么

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

    php進程通信之信號量的作用是什么

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

    php進程通信之信號量的作用是什么

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

    php進程通信之信號量的作用是什么

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

    信號量類型

    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,但很不幸,并不是如此,我們對上面的腳本執行一下:

    php進程通信之信號量的作用是什么

    運行了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進程通信之信號量的作用是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    php
    AI

    垫江县| 盐亭县| 麦盖提县| 巫山县| 东方市| 龙山县| 左云县| 定结县| 股票| 上栗县| 阿瓦提县| 肇源县| 泸州市| 晋宁县| 涞源县| 方山县| 明水县| 黄浦区| 响水县| 武城县| 兴化市| 安新县| 北川| 九龙县| 若尔盖县| 舞阳县| 法库县| 曲阳县| 武鸣县| 本溪市| 巫溪县| 利辛县| 永仁县| 青浦区| 西宁市| 平邑县| 家居| 安庆市| 东兰县| 台东县| 常熟市|