這部分 GCC 并沒(méi)有提供實(shí)現(xiàn),也就是說(shuō)GCC沒(méi)有義務(wù)提供這個(gè)實(shí)現(xiàn),我們只能用一些第三方的實(shí)現(xiàn)。
看不懂這一次GCC什么用意,都四年過(guò)去了。
所以現(xiàn)在在寫跨平臺(tái)多線程的程序時(shí)我一般選擇使用 Qt 這個(gè)框架(C++)。
當(dāng)然,C語(yǔ)言發(fā)展了這么多年了,自然少不了自己的第三方庫(kù),實(shí)際上標(biāo)準(zhǔn)庫(kù)只提供了很小的一部分內(nèi)容,甚至連某些常用的數(shù)據(jù)結(jié)構(gòu)都未曾實(shí)現(xiàn),我們?cè)撘恢狈磸?fù)造輪子嗎?
當(dāng)然不!
在這個(gè)C的變成世界里,有許多實(shí)用的庫(kù),其中最有名的且最通用(跨多個(gè)平臺(tái)的實(shí)現(xiàn)包括Windows,要知道很多實(shí)用的編程庫(kù)都不提供Windows的實(shí)現(xiàn))就是GLib這個(gè)庫(kù),其中就有實(shí)現(xiàn)線程的部分。
但是,因?yàn)檫@是中文的,看的人自然不是歪果仁,中國(guó)編程新手大都還是習(xí)慣用 Windows 環(huán)境,也不做強(qiáng)求,仁者見(jiàn)仁智者見(jiàn)智,后續(xù)會(huì)有一個(gè)程序作為例子,其中簡(jiǎn)單的應(yīng)用了多線程的知識(shí)來(lái)寫一個(gè)備份軟件,線程的實(shí)現(xiàn)是用的 Windows 自己的接口,所有這些接口都能在 MSDN 里查找到相應(yīng)文檔。
之所以不說(shuō) *nix 系統(tǒng)下的配置是因?yàn)?,哪里的配置太無(wú)腦了,特別是Ubuntu,一句命令+有網(wǎng)絡(luò)基本就配置完畢了。
如果資源太少,可以參考如何編譯GTK項(xiàng)目的方法,因?yàn)?strong>GLib的前身便是GTK的一部分,只不過(guò)后來(lái)獨(dú)立出來(lái)了。
微軟的宇宙級(jí)編譯器Visual Studio對(duì)于C89(C90)之后的標(biāo)準(zhǔn)并不支持,但是對(duì)其中的特性卻早早進(jìn)行了實(shí)現(xiàn)(即沒(méi)有可開(kāi)啟標(biāo)準(zhǔn)的選項(xiàng),但是新標(biāo)準(zhǔn)所說(shuō)的特性它都擁有,都能夠使用,甚至還要更加超前)
glib\glib2.28\include目錄,不放心的還可以再添加一個(gè)glib\glib2.28\lib\glib-2.0\include目錄 glib\glib2.28\lib目錄glib\glib2.28\lib目錄下的所有.lib文件,即將這些文件的名字都手動(dòng)輸入進(jìn)去,如果使用我的這個(gè)版本的話那就是gio-2.0.lib glib-2.0.lib gthread-2.0.lib gmodule-2.0.lib gobject-2.0.lib多線程/MT是很多人(比如知乎的回答人和提問(wèn)者),都提到要多觀看C的源代碼, 但是這對(duì)于初學(xué)者,甚至現(xiàn)在的我感覺(jué)也不是一件容易的事,更遑論初入門的同學(xué)了,特別是對(duì)于許多上個(gè)世紀(jì)的大神,為了節(jié)省空間以及提高效率,簡(jiǎn)直是無(wú)所不用其極!雖然某些用法能夠被現(xiàn)代接受,但是你能在第一眼就看出來(lái),為了構(gòu)造一個(gè)紅黑樹(shù)節(jié)點(diǎn),把樹(shù)的指針和節(jié)點(diǎn)的顏色信息都隱藏在一個(gè)指針地址里嗎?
/* 假設(shè)有一個(gè)節(jié)點(diǎn)的指針 p_node */
node_color = p_node->node_color & 1; /* 原理就是用最后一位bit來(lái)存儲(chǔ)顏色 */
其中在 Linux 里, p_node->node_color 被設(shè)定為無(wú)符號(hào)的長(zhǎng)整形,以整數(shù)型式存儲(chǔ)指針和顏色信息,而不是用指針類型。
node_pointer = (node_type*)p_node->node_color & ~3;/* 清除最后兩位上的bit的值 */
也就是清除顏色信息,留下的就是指針的值,即地址。
為什么呢,只要我么能夠保證節(jié)點(diǎn)的創(chuàng)建位置是32位/64位對(duì)齊的,我們就能夠保證它的最后兩位/三位是空的,絕對(duì)不會(huì)被使用的。
/* 32位 */
sizeof(void*); /* 是 4 */
/* xxxx xxxx xxxx xxxx xxxx xxxx xxxx xx00 */
/* 64位 */
sizeof(void*); /* 是 8 */
/* 前方省略48位 xxxx xxxx xxxx x000 */
意思就是,對(duì)于指針而言,因?yàn)榫幾g器要保證尋址的高效所以它在給分配地址的時(shí)候,會(huì)對(duì)齊內(nèi)存中的地址,按照指針大小的倍數(shù)對(duì)齊,這就會(huì)導(dǎo)致不同位的程序的指針變量的值中有幾個(gè)bit 會(huì)沒(méi)有使用,則用它來(lái)存儲(chǔ)。
是
接下來(lái)的第三部分我會(huì)用一個(gè)備份程序來(lái)貫穿
Win32 APIVisual Studio 2013Pure C Programing Language會(huì)在里面介紹一下,常在開(kāi)源代碼中看見(jiàn)的一些奇怪的東西,例如
#ifdef __cplusplus
extern "c" {
#endif
...
#ifdef __cplusplus
}
#endif
這到底是什么