使用者執行緒的切換,是核心決定,由排程器分配時間片排程到核心空間,轉換成核心執行緒,然後指令重排序交給cpu.cpu沒有執行過程中的中斷時間,是不斷的在執行,只是排程器提前將執行緒排程好,將多個執行緒的指令排好交給cpu。那麼這種混合插入就是我們上層理解的執行緒排程。對cpu而言,所有的執行緒都是 序列的。
對於乙個多執行緒併發的多次處理或者重複處理乙個任務,如果這個任務就是原子操作,(如讀、寫操作,先是定址,然後讀出資料,再然後定址找到要寫回來的位址將資料寫進來;也有可能是指標操作,先是定址,讀出改位址裡儲存的位址資料,然後定址跳轉,找到指向的位址,將資料讀出來,然後再定址,將資料寫進去。那麼這一長串的操作就是原子操作,中間不可能有排程器在排程指令的時候,將這些指令分割開來處理。)對於單個cpu系統而言,那麼沒有必要同步或者互斥同步。互斥就是單個cpu最基本的特性,只要有乙個執行緒在執行,那麼其他的互斥執行緒都在停止狀態。排程器會記錄有互斥的執行緒,在排程的時候不會去排程。對於原子操作不可能有排程器的中斷,這是硬體指令集決定的,所以是硬體決定的。硬體會在原子操作上,分配一定時長的操作時間。而排程器分配的時間片就是基於這個操作時間的,是操作時間的整數倍。
阻塞,核心將執行緒剔除到使用者空間,這樣很耗費資源,因為系統核心是不能被使用者空間訪問的;因為核心是完全保護起來的,這也是系統穩定很重要的因素。但是核心空間可以訪問使用者空間,通知執行緒被排程到核心區。那麼執行緒從使用者區進去到核心區,那麼必然有儲存空間在核心區重新建立,資料重新讀取到核心中。相反,從核心中將執行緒剔除,依然有資料從核心區讀到使用者儲存區。為了優化或者減少執行緒的阻塞,首先可以判斷執行緒將要執行的**是不是有鎖,而且和已執行或者執行過的執行緒存在鎖互斥。如果存在就不被排程,等待下一次排程。或者在排程的時候沒有鎖機制的判斷,如果被排程的執行緒存在所互斥,那麼暫停被排程,直接將分配的時間片轉移到下乙個要排程的執行緒。也可以
在排程處理的時候發現要執行的**是含有鎖互斥的**,那麼轉移到沒有鎖存在的**先執行。總之減少執行緒什麼也沒有做,便從核心剔除到使用者空間。
那麼為什麼作業系統發現,互斥的執行緒,將其剔除到使用者空間呢,重新排隊進入到核心空間,然後逐步分配時間片等待排程呢?這個是出於安全考慮,或者系統核心的設計。系統核心設計上,在核心中的執行緒都會安排到時間片,也就是都會被排程器排程。沒有等待的概念,等待的概念只在使用者空間。在使用者空間等待排隊,那麼在核心中就沒有對應的執行的核心執行緒(將使用者空間的執行緒指令copy到核心空間去執行)。所以這也是為什麼將互斥的執行緒調到使用者空間排隊,是防止再被排程到。
那麼為什麼作業系統分為使用者空間和核心空間呢?你可以想象,使用者在操作的時候很可能隨時刪除乙個執行緒(關閉),和建立(開啟)乙個新的執行緒,使用者這些操作如果直接對映對應到核心上,會導致排程器自我調整的時間很少,核心還要丟擲一部分資源來監聽和相應使用者操作(這也就是將現在的作業系統將使用者空間和核心合併在一起而且也可以通訊)。那麼系統可能不穩定,綜合設計經驗,作業系統將只顧和cpu打交道的部分封裝為核心,相應使用者的部分封裝為使用者區。
對於多核處理器系統,那麼執行緒的併發可以是多個cpu同時處理,也可以多個執行緒在切換時間片中處理,那麼考慮執行緒的死鎖和同步,互斥就要考慮其他cpu是不是會處理。
同步處理的資料如何同步,保證資料的統一性。
linux系統的互斥鎖機制
2016年12月16日 17 34 48 這兩天開始看linux下的執行緒程式設計,看到了關於互斥鎖這一塊兒,寫了乙個小例項如下 但是偶爾結果也會是這樣子的 就被掛起了,不執行向下的操作了。最後想來了問題所在 輸出1的那個執行緒如果先執行,輸出2的執行緒接下來執行,輸出3的執行緒最後執行。那麼到了p...
作業系統 自旋鎖(spin)與互斥鎖(mutex)
程式在多處理器上執行會因為,多個執行緒同時進行,而導致喪失語句的原子性。例如讀和寫的操作是分開的,不能保證同時完成。所以軟體不夠用硬體來湊,通過硬體實現一條指令完成讀寫 這就是自旋鎖。可以理解為乙個房間門口桌上只放一把鑰匙,每次有人想進就用其他東西交換鑰匙,拿到鑰匙才能進入房間,拿不到鑰匙的就重複嘗...
linux多執行緒 作業系統執行緒同步互斥
這一目主要我想得是理論和實際結合的辦法去做,先將理論,把這塊在作業系統中的內容先進行陳述。然後用linux下的 去真正實現。perterson演算法是用來是實現對臨界區資源的互斥訪問,它是用軟體的機制實現。也就是說在linux系統程式設計當中,如果不讓你使用pthread mutex t mutex...