1. 程式人生 > >跟濤哥一起學嵌入式第11集:一個實現鎖機制非常有意思的巨集

跟濤哥一起學嵌入式第11集:一個實現鎖機制非常有意思的巨集

QQ群(宅學部落)有位學員問了一個很奇怪的巨集,覺得很有意思,特拿來分享,它的定義如下:

跟濤哥一起學嵌入式第11集:一個實現鎖機制非常有意思的巨集

我們知道,巨集定義其實就是為了方便,給一串程式碼字串定義一個別名。有時候字串過於複雜,我們可以分多行書寫,然後使用邏輯連線符“\”連線起來,表示一個完整的字串。但是分析上面的巨集定義,你會發現它分別定義了2個巨集,但是呢,又使用了一對大括號括起來,很有欺騙性:看起來很像語句表示式,但是呢,有沒有小括號括起來,是不是很奇怪?
呼叫的時候,使用方法更是奇怪,如果我們單獨使用AA()或BB()呼叫,你會發現編譯根本通不過,這是為什麼呢?我們可以使用命令對上面的程式作預處理展開:
$ gcc -E main.c
前處理器對巨集定義展開後,你會發現,會報語法錯誤,但是我們通過AA();BB();這種呼叫方式呢,就可以避免語法錯誤,可以順利編譯通過並執行。
這兩個有意思的巨集,要成對出現,才能避免程式編譯錯誤,如果你只使用了其中一個,程式就編譯通不過,徹底歇菜了。這是誰寫的程式碼啊?為什麼要這麼寫?其實正是這對巨集的有意思之處,我們可以稍作封裝:

跟濤哥一起學嵌入式第11集:一個實現鎖機制非常有意思的巨集

通過上面的修改,你會發現這對巨集變成了一對加鎖加鎖功能,可以實現原子操作的臨界區功能。而且更巧妙的是這對巨集利用了C語法編譯檢查,強制程式設計師成對使用,否則就會報語法編譯錯誤。因此,這種強制成對使用,也就避免了加鎖解鎖不成對出現時引起的死鎖問題。
C語言博大精深,任何一段程式碼仔細分析,仔細推敲,都有很多程式設計技巧和精華在裡面,感覺該學員提出的一個好問題,也歡迎更多的學員遇到問題踴躍提問、勤于思考,大家一起學習、努力、進步。