Win7之家( afsion.com.cn):探秘 Windows 7 系統(tǒng)中的 POSIX 子系統(tǒng)
《Windows Internals 5e》第二章開頭提到了1989年Windows NT最初設(shè)計時的設(shè)計要求,其中倒數(shù)第二條是:
Meet government requirements for POSIX 1003.1 compliance。
Windows NT一直提供了POSIX子系統(tǒng),但是在最近的若干版本中,一直沒有默認安裝上。
要在Windows 7中安裝,第一步是在“打開或關(guān)閉系統(tǒng)功能”中選中“基于UNIX的應(yīng)用程序子系統(tǒng)”一項,如圖所示:
稍等過后,我們就可以使用基于Windows NT的POSIX子系統(tǒng)的POSIX應(yīng)用程序了。...好拗口,不過咱還是得稍微提醒一下,就算使用POSIX的庫,但是如果不是使用基于Windows的編譯器,還是沒法運行的。從這個角度說,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)進程的映像,其地位就像csrss.exe之于Windows子系統(tǒng)一樣。psxss.exe將會在系統(tǒng)首次運行POSIX應(yīng)用程序的時候啟動,其生命周期一直截止到系統(tǒng)關(guān)閉為止。psxdll.dll就是POSIX庫文件,對POSIX庫的調(diào)用最終都將落到它的手中。...不過它的主要任務(wù)其實是將POSIX系統(tǒng)調(diào)用轉(zhuǎn)換為Windows系統(tǒng)調(diào)用,再調(diào)用Windows子系統(tǒng)的相關(guān)功能來完成任務(wù)。畢竟是Windows的地盤,有道是強龍難壓地頭蛇,更何況這地頭蛇的能耐還不輸強龍呢。再看那個%SystemRoot%/posix.exe,它將會成為POSIX子系統(tǒng)的會話管理進程,只要有任何POSIX應(yīng)用程序運行,它就會存在;而如果所有POSIX進程都已經(jīng)終結(jié),這個進程也會被殺死。
但是現(xiàn)在我們還是不能自行編寫POSIX應(yīng)用程序,也不能像在Unix中一樣使用C Shell和Unix Perl,這些都是需要額外下載的。微軟提供了Utilities and SDK for Subsystem for UNIX-based Applications,其中包含了一系列源于SVR-5和BSD的實用程序和命令,開發(fā)所需的頭文件和庫,以及一套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子菜單了。展開它看看,一共有兩個菜單項:Download Untilities for Subsystem for UNIX-based Applications和What’s new in Subsystem for UNIX-based Applications兩項。Download Untilities for Subsystem for UNIX-based Applications就是指向Utilities and SDK for Subsystem for UNIX-based Applications下載頁的鏈接——不過是Windows Server 2008和Windows Vista的版本-_-|||請使用What’s new in Subsystem for UNIX-based Applications首頁上提供的鏈接(最終會指向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)有了更多選項了:
嗯,除了超鏈接和幫助之外就全是我們剛剛裝上的那些工具中的Shell那部分了。微軟為POSIX子系統(tǒng)提供了數(shù)百款來源于UNIX的工具可以使用,而這些工具都是基于Windows POSIX子系統(tǒng)直接使用GNU原生的代碼編譯的?梢哉f這幾百個工具也是Windows POSIX子系統(tǒng)對于POSIX.1提供的良好支持的明證...只是,那個版本實在是太舊了...上一個圖對比一下微軟為POSIX子系統(tǒng)提供的vim工具和opensolaris 2009.06當中提供的vim工具:
由圖可見,微軟提供的還是14年以前的版本呢。雖然不是不能理解,不過微軟對這個POSIX子系統(tǒng)還真是不上心啊...
注意,啟動Shell(我用的是C Shell)之后的當前目錄好像是當前用戶的目錄...確實是UNIX的風格的說...可以輸入cd /跳轉(zhuǎn)到根目錄下。輸入ls -l看看~哈哈,充滿UNIX風格的目錄列表呈現(xiàn)在面前。不過,這些目錄都是原原本本的Windows目錄,而根目錄其實就是你在安裝Untility and SDK for SUA時選擇的目錄。正因如此,你會發(fā)現(xiàn)所有目錄的owner竟然都是Windows的用戶組:
如果要通過POSIX子系統(tǒng)造訪Windows的文件系統(tǒng),請先進入/dev/fs下。該目錄下面的虛擬目錄,就是你的Windows磁盤驅(qū)動器的映射。提醒一下,UNIX是區(qū)分大小寫的哦。
微軟為POSIX子系統(tǒng)提供了兩套GCC,分別是3.3和4.2.0...呃,后者還是GCC第一個支持OpenMP的版本。我們不妨試著編譯UNIX-Only的程序看看。話說我對UNIX編程實在不太擅長,因此就寫一個簡單的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í)行看看了。寫代碼當然可以使用vi了,不過我用的是UltraEdit。別忘了保存的時候?qū)⒕幋a選成ASCII,把換行符選成UNIX樣式咯。
OK,這樣就運行出來了。話說,gcc的反應(yīng)好象比在OpenSolaris里面慢一點啊。就這么抵觸微軟嗎?
不過這里編譯出來的應(yīng)用程序,自然是沒法在UNIX操作系統(tǒng)下運行的。相反,只要給它加上個exe后綴,就可以像平常運行Windows應(yīng)用程序一樣通過POSIX子系統(tǒng)運行它。作為本文的結(jié)束,我們來做一個小小的實驗:
首先,稍微修改一下剛剛的代碼:
-
#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進程。找一個好用一點的進程監(jiān)視軟件(推薦Sysinternals的Process Explorer),看看現(xiàn)在的進程狀況。大致應(yīng)該如下所示:
需要注意的是posix.exe進程已經(jīng)不存在了;叵肭拔乃,posix.exe是POSIX的會話進程,沒有posix.exe也就間接說明了沒有POSIX應(yīng)用程序正在運行。
現(xiàn)在我們啟動剛才編譯的程序,現(xiàn)在Process Explorer的界面應(yīng)該如下所示:
嗯嗯,我們的程序和它fork出的子進程正在高高興興地運行著,因為我們在程序中添加了死循環(huán)所以進程不會立刻退出,而是像沒有出口的自旋鎖一樣饕餮著CPU資源...嗯,這些都不重要,重要的是posix.exe的重回人間——在上面的截圖中就是那個pid為5556的進程,F(xiàn)在,只要我們在運行著test1.exe的Shell中按下Ctrl+C,test1.exe父子就和posix.exe先生一起去進程天國報到了^^
(順便插一句題外話,.Net Framework 4的TPL中好像有提供SpinLock結(jié)構(gòu)支持自旋鎖的功能,雖然使用自旋鎖的花銷會比較小,但是請謹慎使用這個結(jié)構(gòu),尤其是不要用于可能發(fā)生長時間鎖定的操作——否則會發(fā)生什么,請參見上圖驟然上漲的CPU使用率曲線...畢竟自旋鎖就是通過循環(huán)實現(xiàn)的,不同于互斥鎖,自旋鎖會一直處于忙等的狀態(tài),直到時間片結(jié)束,然后是下一個時間片...下下個時間片...)
評論列表
查看所有 條評論