原子量的理解
我們知道電晶體有兩種狀態,通電和不通電,對應著二進位制儲存中的1和0,這和開關的原理是一樣的,不過開關可以由人來控制,而電晶體的狀態是由電來控制的;我們可以利用一種特殊的閘電路組合控制乙個電晶體中的狀態不再受所通入電流的影響,可以說是把一位數存到了這個電晶體裡面;當需要讀取時,開放電晶體的後端就可以讓其中儲存的狀態流出來;當需要改寫時,通過一種特殊的閘電路組合又可以控制這個電晶體受流通電流的影響,這時就可以改變儲存在其中的值。
在彙編中要改寫乙個資料通常需要三步,從記憶體中取出資料到暫存器,在暫存器中修改,再將資料存回記憶體,即ldr r0,0x10000040 mov r1,#4 str r1,[r0] 也就是說修改乙個位址處存的數值不是一步完成的,而在c語言中這是一步完成的:*p=4(假設*p=0x10000040)。
我們知道指標的本質就是對應儲存的資料被解釋為乙個位址,而對於類似變數這種對應儲存的資料被解釋為乙個對應型別的數值,儲存的都是乙個數,只是在不同環境下被解發布來的含義不一樣而已。由上面解釋的電晶體的物理狀態可知,乙個電晶體同一時間只能儲存一種狀態,組合起來就是乙個記憶體塊同一時間只能儲存乙個固定不變的值,也就是說乙個指標同一時間只能指向乙個固定的位址;然而乙個記憶體塊的位址卻可以儲存在多個指標對應的記憶體塊中,也就是說可以同時有多個指標指向同一塊記憶體,總結起來就是時間上唯一,空間上不唯一。
由於有這種屬性,當有多個指標指向同一塊記憶體,並通過其中某乙個指針對指向的資料進行修改後,再通過其他指標取得的這個記憶體塊的資料是那個已經被改變後的值。因為修改乙個位址的值需要至少需要三步,而核心又是搶占式的,現在我們假設有兩個指標a,b同時指向了同一塊記憶體m,當我們執行執行緒1用指標a取出這個記憶體的資料準備運算時,發生了程序排程,跳到執行緒2執行,此時指標b也取出了這個資料準備運算時也發生了程序排程返回到執行緒1執行,指標a修改值後又存回這個記憶體,如果在程序1用的這個記憶體資料之前執行緒2執行將資料修改後存入這個記憶體位址,那麼執行緒1取得的數值將不再是它本身儲存的那個而且它以為它是沒錯的,就會發生資料錯誤。
針對以上假設的這種情況,經常把全域性變數設定為原子量,在指令上使得對這個全域性變數的取出、賦值、存回是不可被打斷的,這就對應著c語言中的一條語句。
在linux kernel裡面原子量定義如下:
typedef struct atomic_t;
驅動中的同步互斥阻塞之原子量
1.原子操作 原子操作指的是在執行過程中不會被別的 路徑所中斷的操作 常用原子操作函式舉例 atomic v v atomic init 0 定義原子變數v並初始化為0 atomic read atomic t v 返回原子變數的值 void atomic inc atomic t v 原子變數增加...
關於訊號量的學習和理解
在下面這篇博文中學習了race condition,也即如果是要被多個thread共享的共享資源,那麼必須要有訊號量來保護共享資源,以免多個thread同時訪問導致的程式出錯。至於是使用互斥鎖還是讀寫鎖還是什麼鎖,根據需要而定即可。但是鎖用多了就有可能發生死鎖。所謂死鎖,是指兩個或兩個以上的程序在執...
鎖和訊號量的理解
相同點 差異 pthread mutex init pthread mutex destroy pthread mutex lock pthread mutex trylock 輪詢方式加鎖 pthread mutex unlock 非0即1的方式訪問臨界區,只能是獲得鎖的物件才能訪問臨界區,進入臨...