Win7之家( m.airtaxifl.com):探秘 Windows 7 系統(tǒng)中的 POSIX 子系統(tǒng)
《Windows Internals 5e》第二章開頭提到了1989年Windows NT最初設(shè)計(jì)時(shí)的設(shè)計(jì)要求,其中倒數(shù)第二條是:
Meet government requirements for POSIX 1003.1 compliance。
Windows NT一直提供了POSIX子系統(tǒng),但是在最近的若干版本中,一直沒有默認(rèn)安裝上。
要在Windows 7中安裝,第一步是在“打開或關(guān)閉系統(tǒng)功能”中選中“基于UNIX的應(yīng)用程序子系統(tǒng)”一項(xiàng),如圖所示:
稍等過后,我們就可以使用基于Windows NT的POSIX子系統(tǒng)的POSIX應(yīng)用程序了。...好拗口,不過咱還是得稍微提醒一下,就算使用POSIX的庫(kù),但是如果不是使用基于Windows的編譯器,還是沒法運(yùn)行的。從這個(gè)角度說,POSIX子系統(tǒng)也就是方便了UNIX應(yīng)用程序到Windows的移植罷了。順便提一下,Windows的POSIX子系統(tǒng)是基于POSIX.1(IEEE.Std 1003.1-1990;ISO/IEC 9945-1:1990)的.我們不妨稍微看看POSIX子系統(tǒng)給我們帶來的新組件:
其中,%SystemRoot%/System32/psxss.exe是POSIX子系統(tǒng)的環(huán)境子系統(tǒng)進(jìn)程的映像,其地位就像csrss.exe之于Windows子系統(tǒng)一樣。psxss.exe將會(huì)在系統(tǒng)首次運(yùn)行POSIX應(yīng)用程序的時(shí)候啟動(dòng),其生命周期一直截止到系統(tǒng)關(guān)閉為止。psxdll.dll就是POSIX庫(kù)文件,對(duì)POSIX庫(kù)的調(diào)用最終都將落到它的手中。...不過它的主要任務(wù)其實(shí)是將POSIX系統(tǒng)調(diào)用轉(zhuǎn)換為Windows系統(tǒng)調(diào)用,再調(diào)用Windows子系統(tǒng)的相關(guān)功能來完成任務(wù)。畢竟是Windows的地盤,有道是強(qiáng)龍難壓地頭蛇,更何況這地頭蛇的能耐還不輸強(qiáng)龍呢。再看那個(gè)%SystemRoot%/posix.exe,它將會(huì)成為POSIX子系統(tǒng)的會(huì)話管理進(jìn)程,只要有任何POSIX應(yīng)用程序運(yùn)行,它就會(huì)存在;而如果所有POSIX進(jìn)程都已經(jīng)終結(jié),這個(gè)進(jìn)程也會(huì)被殺死。
但是現(xiàn)在我們還是不能自行編寫POSIX應(yīng)用程序,也不能像在Unix中一樣使用C Shell和Unix Perl,這些都是需要額外下載的。微軟提供了Utilities and SDK for Subsystem for UNIX-based Applications,其中包含了一系列源于SVR-5和BSD的實(shí)用程序和命令,開發(fā)所需的頭文件和庫(kù),以及一套Unix Perl(呃...ActivePerl的Windows版本和Linux版的Perl咱也有...咱都快變成Perl收藏家了...),還有Visual Studio調(diào)試插件(windows 7的版本是for Visual Studio 2003/2005/2008的,不支持2010;Vista的版本不支持2008)。
現(xiàn)在在開始菜單中應(yīng)該已經(jīng)有Subsystem for UNIX-based Application子菜單了。展開它看看,一共有兩個(gè)菜單項(xiàng):Download Untilities for Subsystem for UNIX-based Applications和What’s new in Subsystem for UNIX-based Applications兩項(xiàng)。Download Untilities for Subsystem for UNIX-based Applications就是指向Utilities and SDK for Subsystem for UNIX-based Applications下載頁(yè)的鏈接——不過是Windows Server 2008和Windows Vista的版本-_-|||請(qǐng)使用What’s new in Subsystem for UNIX-based Applications首頁(yè)上提供的鏈接(最終會(huì)指向http://www.microsoft.com/downloads/details.aspx?FamilyID=dc03485b-629b-49a6-b5ef-18617d1a9804&displaylang=en)下載基于Windows 7和Windows Server 2008 R2的版本——不只是版本更新,體積也變得小多了,由450M左右下降到了250M左右(說起來Windows SDK的體積也由Windows Vista的1.5G下降到了700M左右了,挺厲害的啊...)
現(xiàn)在開始菜單中應(yīng)該已經(jīng)有了更多選項(xiàng)了:
嗯,除了超鏈接和幫助之外就全是我們剛剛裝上的那些工具中的Shell那部分了。微軟為POSIX子系統(tǒng)提供了數(shù)百款來源于UNIX的工具可以使用,而這些工具都是基于Windows POSIX子系統(tǒng)直接使用GNU原生的代碼編譯的?梢哉f這幾百個(gè)工具也是Windows POSIX子系統(tǒng)對(duì)于POSIX.1提供的良好支持的明證...只是,那個(gè)版本實(shí)在是太舊了...上一個(gè)圖對(duì)比一下微軟為POSIX子系統(tǒng)提供的vim工具和opensolaris 2009.06當(dāng)中提供的vim工具:
由圖可見,微軟提供的還是14年以前的版本呢。雖然不是不能理解,不過微軟對(duì)這個(gè)POSIX子系統(tǒng)還真是不上心啊...
注意,啟動(dòng)Shell(我用的是C Shell)之后的當(dāng)前目錄好像是當(dāng)前用戶的目錄...確實(shí)是UNIX的風(fēng)格的說...可以輸入cd /跳轉(zhuǎn)到根目錄下。輸入ls -l看看~哈哈,充滿UNIX風(fēng)格的目錄列表呈現(xiàn)在面前。不過,這些目錄都是原原本本的Windows目錄,而根目錄其實(shí)就是你在安裝Untility and SDK for SUA時(shí)選擇的目錄。正因如此,你會(huì)發(fā)現(xiàn)所有目錄的owner竟然都是Windows的用戶組:
如果要通過POSIX子系統(tǒng)造訪Windows的文件系統(tǒng),請(qǐng)先進(jìn)入/dev/fs下。該目錄下面的虛擬目錄,就是你的Windows磁盤驅(qū)動(dòng)器的映射。提醒一下,UNIX是區(qū)分大小寫的哦。
微軟為POSIX子系統(tǒng)提供了兩套GCC,分別是3.3和4.2.0...呃,后者還是GCC第一個(gè)支持OpenMP的版本。我們不妨試著編譯UNIX-Only的程序看看。話說我對(duì)UNIX編程實(shí)在不太擅長(zhǎng),因此就寫一個(gè)簡(jiǎn)單的fork好了。
-
#include <unistd.h>
-
#include <stdio.h>
-
int main(int argc,char **argv){
-
if(fork())
-
printf("This is parent process.\n");
-
else
-
printf("This is child process.\n");
-
-
return 0;
-
}
然后輸入如圖的命令,別忘了修改成自己的路徑,然后就可以執(zhí)行看看了。寫代碼當(dāng)然可以使用vi了,不過我用的是UltraEdit。別忘了保存的時(shí)候?qū)⒕幋a選成ASCII,把換行符選成UNIX樣式咯。
OK,這樣就運(yùn)行出來了。話說,gcc的反應(yīng)好象比在OpenSolaris里面慢一點(diǎn)啊。就這么抵觸微軟嗎?
不過這里編譯出來的應(yīng)用程序,自然是沒法在UNIX操作系統(tǒng)下運(yùn)行的。相反,只要給它加上個(gè)exe后綴,就可以像平常運(yùn)行Windows應(yīng)用程序一樣通過POSIX子系統(tǒng)運(yùn)行它。作為本文的結(jié)束,我們來做一個(gè)小小的實(shí)驗(yàn):
首先,稍微修改一下剛剛的代碼:
-
#include <unistd.h>
-
#include <stdio.h>
-
-
int main(int argc,char **argv){
-
if(fork()){
-
printf("This is parent process.\n");
-
for(;;);
-
}
-
else{
-
printf("This is chile process.\n");
-
for(;;);
-
}
-
-
return 0;
-
}
-
使用GCC編譯這段代碼并將編譯所得的程序修改為exe后綴,隨后關(guān)閉所有的POSIX進(jìn)程。找一個(gè)好用一點(diǎn)的進(jìn)程監(jiān)視軟件(推薦Sysinternals的Process Explorer),看看現(xiàn)在的進(jìn)程狀況。大致應(yīng)該如下所示:
需要注意的是posix.exe進(jìn)程已經(jīng)不存在了。回想前文所述,posix.exe是POSIX的會(huì)話進(jìn)程,沒有posix.exe也就間接說明了沒有POSIX應(yīng)用程序正在運(yùn)行。
現(xiàn)在我們啟動(dòng)剛才編譯的程序,現(xiàn)在Process Explorer的界面應(yīng)該如下所示:
嗯嗯,我們的程序和它fork出的子進(jìn)程正在高高興興地運(yùn)行著,因?yàn)槲覀冊(cè)诔绦蛑刑砑恿怂姥h(huán)所以進(jìn)程不會(huì)立刻退出,而是像沒有出口的自旋鎖一樣饕餮著CPU資源...嗯,這些都不重要,重要的是posix.exe的重回人間——在上面的截圖中就是那個(gè)pid為5556的進(jìn)程。現(xiàn)在,只要我們?cè)谶\(yùn)行著test1.exe的Shell中按下Ctrl+C,test1.exe父子就和posix.exe先生一起去進(jìn)程天國(guó)報(bào)到了^^
(順便插一句題外話,.Net Framework 4的TPL中好像有提供SpinLock結(jié)構(gòu)支持自旋鎖的功能,雖然使用自旋鎖的花銷會(huì)比較小,但是請(qǐng)謹(jǐn)慎使用這個(gè)結(jié)構(gòu),尤其是不要用于可能發(fā)生長(zhǎng)時(shí)間鎖定的操作——否則會(huì)發(fā)生什么,請(qǐng)參見上圖驟然上漲的CPU使用率曲線...畢竟自旋鎖就是通過循環(huán)實(shí)現(xiàn)的,不同于互斥鎖,自旋鎖會(huì)一直處于忙等的狀態(tài),直到時(shí)間片結(jié)束,然后是下一個(gè)時(shí)間片...下下個(gè)時(shí)間片...)
評(píng)論列表
查看所有 條評(píng)論