死結,並發,並行,搶購概念的很多疑惑

來源:互聯網
上載者:User
關鍵字 php mysql linux

首先,死結是怎樣產生的 ?

網上的好多回答都是照搬的如下概念:

產生死結的四個必要條件:

  1. 互斥條件:一個資源每次只能被一個進程使用。

  2. 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。

  3. 不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪。

  4. 迴圈等待條件:若干進程之間形成一種頭尾相接的迴圈等待資源關係。*

我的問題是:看了這裡的介紹 , 發現貌似並發確實是會產生死結的, 個人認為, 因為並髮狀態下, 可能CPU在處理某個進程的時候, 其他進程需要等待CPU切換過來找自己, 等待的過程我個人覺得就是阻塞著,也就是死結著, 不知道理解對不對 !

另外, 看到很多人說搶購/秒殺系統, 在高並發下會帶來多賣的風險, 這個我就更加不能理解了 :

按照我小菜的思維, 假設搶購1000個商品, 假設有100個請求在某一個CPU時間內一次性擠入了CPU內, 假設CPU是單核的, 那麼並發不是CPU一個個不斷地切換處理麼? 既然這樣, 也就是CPU會一個個地處理對商品的減操作, 這樣的話, 每次操作的時候我判斷商品剩餘數量不就行了, 怎麼可能多賣!!! 所以這裡需要大牛稍微幫忙給解釋一下

還有就是並行

假設有4個請求在某一個CPU時間內一次性擠入了CPU內, 而我們的CPU是4個核心的, 那麼四個核心同時處理4個搶購進程進行商品數量遞減的時候, 這個小菜認為: 這倒是確實會出現同時鎖住這條商品記錄導致任何一個核心都無法釋放而產生死結! 但問題是:

  1. 自己底層知識不夠, 不知道是不是這4個請求一定就會分配個每個核心, 還是會全部分配到一個核心上, 再或者說壓根就是隨機分配 (比如核心一上2個請求,核心二上1個請求,核心三上1個請求,核心4上沒有請求)? 但不管怎麼說, 既然死結了, 也不會出現搶購超賣了啊!

  2. 第二個問題是: 如果請求數量大於4個, 比如說又是100個一次性擠入了CPU內, 這時候, 又出現了並發, 而不是並行, 可能每個CPU都會進行輪訓處理並發的請求 ;

回複內容:

首先,死結是怎樣產生的 ?

網上的好多回答都是照搬的如下概念:

產生死結的四個必要條件:

  1. 互斥條件:一個資源每次只能被一個進程使用。

  2. 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。

  3. 不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪。

  4. 迴圈等待條件:若干進程之間形成一種頭尾相接的迴圈等待資源關係。*

我的問題是:看了這裡的介紹 , 發現貌似並發確實是會產生死結的, 個人認為, 因為並髮狀態下, 可能CPU在處理某個進程的時候, 其他進程需要等待CPU切換過來找自己, 等待的過程我個人覺得就是阻塞著,也就是死結著, 不知道理解對不對 !

另外, 看到很多人說搶購/秒殺系統, 在高並發下會帶來多賣的風險, 這個我就更加不能理解了 :

按照我小菜的思維, 假設搶購1000個商品, 假設有100個請求在某一個CPU時間內一次性擠入了CPU內, 假設CPU是單核的, 那麼並發不是CPU一個個不斷地切換處理麼? 既然這樣, 也就是CPU會一個個地處理對商品的減操作, 這樣的話, 每次操作的時候我判斷商品剩餘數量不就行了, 怎麼可能多賣!!! 所以這裡需要大牛稍微幫忙給解釋一下

還有就是並行

假設有4個請求在某一個CPU時間內一次性擠入了CPU內, 而我們的CPU是4個核心的, 那麼四個核心同時處理4個搶購進程進行商品數量遞減的時候, 這個小菜認為: 這倒是確實會出現同時鎖住這條商品記錄導致任何一個核心都無法釋放而產生死結! 但問題是:

  1. 自己底層知識不夠, 不知道是不是這4個請求一定就會分配個每個核心, 還是會全部分配到一個核心上, 再或者說壓根就是隨機分配 (比如核心一上2個請求,核心二上1個請求,核心三上1個請求,核心4上沒有請求)? 但不管怎麼說, 既然死結了, 也不會出現搶購超賣了啊!

  2. 第二個問題是: 如果請求數量大於4個, 比如說又是100個一次性擠入了CPU內, 這時候, 又出現了並發, 而不是並行, 可能每個CPU都會進行輪訓處理並發的請求 ;

  1. PHP是進階語言,不用考慮CPU的問題,每個請求都會分配給一個進程,php自己會去管理進程調用什麼資源的。你說的死結,應該是資料庫的吧,不是進程的。

  2. 100個進程擠進去一個CPU。。CPU也會正常去一個個處理完的。。。

好了。。來說說你問的問題吧。。我嘗試梳理了好久猜測你問的是啥。。簡單的說下吧。。

死結是怎麼產生的

籠統點說。mysql每次對某一堆資料修改或者查詢(innodb在某些條件下不受這個限制)的時候。。。會告訴系統,這片資料我要用。。別人不能動。。。然後別人再來用的時候,系統就會告訴別人。。某某某在用著這片資料,你等等。。然後別人就等著了。。。這就叫鎖。。
那死結是怎麼回事呢?有的資料是有關聯的,例如秒殺,你要先扣庫存,還要寫訂單。。所以就會高速系統,庫存這個你先給我鎖住,等我寫完訂單回來,改完庫存,你再把兩個都放開。。。
如果這時候有另外一個人執行著相反的事情。。要先鎖住訂單表。然後去改庫存表。
那就可能死結,來縮時攝影類比下。。。

A:系統!鎖庫存表,我要去寫訂單表。。 系統:好的!搞定。。 B:系統!鎖訂單表,我要去改庫存表。。 系統:好的!搞定。。

A:系統,我要寫訂單~ 系統:抱歉,B使用者佔用著,你等等。 A: 哦~

B:系統,我要改庫存表 系統:抱歉,A使用者佔用著,你等等。 B: 哦~

幾個小時過去了... A:B搞什麼鬼,還沒用完。。 B:A搞什麼鬼,還沒用完。。

伺服器:你們搞什麼鬼,幾百萬使用者等著呢。。

理解了嗎?附代碼:

SELECT `product` WHERE `pid` = 1 FOR UPDATA;UPDATA `order` SET `status` = 1 WHERE `uid` = 2 AND `pid` = 1;
SELECT `order` WHERE `uid` = 2 FOR UPDATA;UPDATA `product` SET `num` = `num` + 1 WHERE `oid` = 3;

想真實體驗,就讓他兩條中間sleep幾秒,同時請求兩邊,就鎖住了,直到逾時

這個確實把死結說的很清楚了,原來死結是這麼產生的,我問題中的死結也確實是資料庫的死結
那對於死結,我覺得是個碰巧出現的事情,覺著商務邏輯如果很複雜的話,還是很容易出現這種巧合的,比如innodb下一個商務邏輯1需要一個事務(會操作a,b兩張表各自的某條記錄)進行完成時候,完全有可能在操作進行到a表某條記錄操作剛完成的時候,也就是正準備操作b表記錄時; 突然間有另一條商務邏輯2請求被cpu切換到了(巧了,它也用事務並且先操作b表的同邏輯1的記錄,再操作
a表同邏輯1的記錄),而他正好操作完b表的該條記錄,準備請求這樣目前被鎖住的情況就導致邏輯一不能進行,邏輯二也不能進行! 理解的對嗎?

那對於為什麼並發會產生多賣我還沒有清楚啊,如若按照你說的,cpu總會一個個的處理請求, 那處理每個請求的時候我都判斷當前庫存,根本不會出現超出庫存的啊

還有,您說的並發是一個一個請求進行處理 這是單cpu會出現的或者請求數大於cpu個數會出現的

如果是cpu有5顆,只過來3個請求,每個請求都要操作a表的1記錄,那還真有可能3顆cpu並行同時抓住a表的1記錄,這樣也是死結嗎? 還是說,雖然cpu並行到達這條記錄,但資料庫只會允許一個個來加鎖,即使同時到達,但mysql還是會排隊,這並不算死結?

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.