多线程的原子锁
? ?原子鎖是多線程編程中的一個特色。然而,在平時的軟件編寫中,原子鎖的使用并不是很多。這其中原因很多,我想主要有兩個方面。第一,關于原子鎖這方面的內容介紹的比較少;第二,人們在編程上面習慣于已有的方案,如果沒有特別的需求,不過貿然修改已存在的代碼。畢竟對很多人來說,不求有功,但求無過。保持當前代碼的穩定性還是很重要的。 ?
?? ?其實,早在《 多線程數據互斥 》這篇博客中,我們就已經介紹過原子鎖。本篇博客主要討論的就是原子鎖怎么使用。中間的一些用法只是我個人的一些經驗,希望能夠拋磚引玉,多聽聽大家的想法。
unsigned?int?count?=?0;?? ?? int?find_data_process()?? {?? ????if(/*?data?meets?our?standards?*/){?? ?????????EnterCriticalSection(&cs);?? ?????????count?++;?? ?????????LeaveCriticalSection(&cs);??????????? ????}?? }??
?? ?我們看到代碼中間使用到了鎖,那么勢必會涉及到系統調用和函數調度。所以,在執行效率上會大打折扣。那么如果使用原子鎖呢?
unsigned?int?count?=?0;?? ?? int?find_data_process()?? {?? ????if(/*?data?meets?our?standards?*/){?? ????????InterLockedIncrement(&count);?? ????}?? }??
void?data_process()?? {?? ????EnterCriticalSection(&cs);?? ????do_something();?? ????LeaveCriticalSection(&cs);????? }??
?? ?如果改成原子鎖呢,會是什么樣的呢?
[cpp]?view plaincopy unsigned?int?lock?=?0;?? ?? void?data_process()?? {?? ????while(1?==?InterLockedCompareExchange(&lock,?1,?0));?? ????do_something();?? ????lock?=?0;?????? }??
?? ?其實,早在《 多線程數據互斥 》這篇博客中,我們就已經介紹過原子鎖。本篇博客主要討論的就是原子鎖怎么使用。中間的一些用法只是我個人的一些經驗,希望能夠拋磚引玉,多聽聽大家的想法。
?? ?(1)查找函數中原子鎖????
?? ?在一些函數當中,有的時候我們需要對滿足某種特性的數據進行查找。在傳統的單核CPU上,優化的空間比較有限。但是,現在多核CPU已經成了主流配置。所以我們完全可以把這些查找工作分成幾個子函數分在幾個核上面并行運算。但是,這中間就會涉及到一個問題,那就是對公共數據的訪問。傳統的訪問方式,應該是這樣的,
[cpp]?view plaincopy
?? ?我們看到代碼中間使用到了鎖,那么勢必會涉及到系統調用和函數調度。所以,在執行效率上會大打折扣。那么如果使用原子鎖呢?
[cpp]?view plaincopy
?? ?有興趣的朋友可以做這樣一道題目,查看0~0xFFFFFFFF上有多少數可以被3整除?大家也可以驗證一下用原子鎖代替臨界區之后,代碼的效率究竟可以提高多少。關于多核多線程的編程,朋友們可以參考《多線程基礎篇》這篇博客。
?? ?(2)代碼段中的原子鎖
?? ?上面的范例只是介紹了統計功能中的原子鎖。那么怎么用原子鎖代替傳統的系統鎖呢?比如說,假設原來的數據訪問是這樣的,
[cpp]?view plaincopy
?? ?這里用原子鎖代替普通的系統鎖,完成的功能其實是一樣的。那么這中間有什么區別呢?其實,關鍵要看do_something要執行多久。打個比方來說,現在我們去買包子,但是買包子的人很多。那怎么辦呢?有兩個選擇,如果賣包子的人手腳麻利,服務一個顧客只要10秒鐘,那么即使前面排隊的有50個人,我們只要等7、8分鐘就可以,這點等的時間還是值得的;但是如果不幸這個賣包子的老板服務一個顧客要1分鐘,那就悲催了,假使前面有50個人,那我們就要等50多分鐘了。50分鐘對我們來說可是不短的一個時間,我們完全可以利用這個時間去買點水果,交交水電費什么的,過了這個時間點再來買包子也不遲。
總結
- 上一篇: 车牌号校验规则,包括新能源车
- 下一篇: 如何修改ZBrush 4R7中工作区颜色