理解PV操作和信號量


對於信號量,可以認為是一個倉庫,有兩個概念,容量和當前的貨物個數。

P操作從倉庫拿貨,如果倉庫中沒有貨,線程一直等待,直到V操作,往倉庫里添加了貨物,為了避免P操作一直等待下去,會有一個超時時間。

V操作往倉庫送貨,如果倉庫滿了,線程等待,直到有P操作,從倉庫中拿走貨物,有空的位置。

創建信號量,設置容量,先有V操作,才能P操作。

 

P操作:貨物個數減1,減過之后,貨物個數大於等於0,說明已經拿到貨物,線程繼續。否者線程阻塞。

V操作:貨物個數加1,加過之后,貨物個數小於等於容量,說明添加成功,線程繼續。否者線程阻塞。

信號量:0≤ 信號量≤容量 ,取值 表示當前可以使用的貨物;

        信號量<0 ,  取值 表示當前等待使用貨物的線程;

            信號量>容量 ,  信號量-容量 表示當前等待添加貨物的線程。

通常,信號量的容量設置很大,可以一直V操作,不會阻塞,但是P操作的時候,很可能阻塞。

當容量為1,也就是互斥,執行流程必定是V操作,P操作,V操作,P操作...


信號量如何做到線程同步?

可以認為信號量關聯一組線程,保存一個指針,指向線程數組的首地址。比如當前信號量為-1,進行P操作,信號量為-2,說明沒有拿到貨物,線程等待,取值為-2,說明有兩個線程等待那貨物。這個時候,其他線程進行V操作,信號量加1,為-1,信號量通知等待的線程中,第一個線程繼續執行,第二個線程繼續等待。

也就是說,P操作等待的情況是減1后,信號量小於0。 P操作繼續執行的情況有兩種:a、減1后,信號量大於等於0,不需等待,直接執行;b、信號量小於0,等待中,其他人進行了V操作,通知這個線程,繼續執行。


項目中的使用場景:

客戶端使用提供的SDk與服務交互,為了提高效率,客戶端發送一個請求后,SDK異步回調給客戶端。但是,有些請求,客戶端希望同步,等待回復。這個時候,建立一個map,以req的sequence為key,value為信號量的指針,信號量的容量設置為1,可用的貨物為0,對信號量進行TimeoutP操作,貨物個數為-1,阻塞在這里。異步回調,收到回復的sequence,根據map找到信號量指針,進行V操作,貨物個數為0,通知前面TimeoutP的線程繼續執行下去,這個時候,TimeoutP的線程,把回復消息取出來,返回給客戶端。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM