1. POSIX 標(biāo)準(zhǔn)
POSIX是Portable Operating System Interface of Unix的縮寫(xiě)。由IEEE(Institute of Electrical and Electronic Engineering)開(kāi)發(fā),由ANSI和ISO標(biāo)準(zhǔn)化。
POSIX的誕生和Unix的發(fā)展是密不可分的,Unix于70年代誕生于Bell lab,并于80年代向美各大高校分發(fā)V7版的源碼以做研究。UC Berkeley在V7的基礎(chǔ)上開(kāi)發(fā)了BSD Unix。后來(lái)很多商業(yè)廠家意識(shí)到Unix的價(jià)值也紛紛以Bell Lab的System V或BSD為基礎(chǔ)來(lái)開(kāi)發(fā)自己的Unix,較著名的有Sun OS,AIX,VMS。由于各廠家對(duì)Unix的開(kāi)發(fā)各自為政,造成了Unix的版本相當(dāng)混亂,給軟件的可移植性帶來(lái)很大困難,對(duì)Unix的發(fā)展極為不利。為結(jié)束這種局面,IEEE開(kāi)發(fā)了POSIX,POSIX在源代碼級(jí)別上定義了一組最小的Unix(類Unix)操作系統(tǒng)接口。
POSIX 表示可移植操作系統(tǒng)接口(Portable Operating System Interface ,縮寫(xiě)為 POSIX 是為了讀音更像 UNIX)。電氣和電子工程師協(xié)會(huì)(Institute of Electrical and Electronics Engineers,IEEE)最初開(kāi)發(fā) POSIX 標(biāo)準(zhǔn),是為了提高 UNIX 環(huán)境下應(yīng)用程序的可移植性。然而,POSIX 并不局限于 UNIX。許多其它的操作系統(tǒng),例如 DEC OpenVMS 和 Microsoft Windows NT,都支持 POSIX 標(biāo)準(zhǔn),尤其是 IEEE Std. 1003.1-1990(1995 年修訂)或 POSIX.1,POSIX.1 提供了源代碼級(jí)別的 C 語(yǔ)言應(yīng)用編程接口(API)給操作系統(tǒng)的服務(wù)程序,例如讀寫(xiě)文件。POSIX.1 已經(jīng)被國(guó)際標(biāo)準(zhǔn)化組織(International Standards Organization,ISO)所接受,被命名為 ISO/IEC 9945-1:1990 標(biāo)準(zhǔn)。
POSIX 現(xiàn)在已經(jīng)發(fā)展成為一個(gè)非常龐大的標(biāo)準(zhǔn)族,某些部分正處在開(kāi)發(fā)過(guò)程中。表 1-1 給出了 POSIX 標(biāo)準(zhǔn)的幾個(gè)重要組成部分。POSIX 與 IEEE 1003 和 2003 家族的標(biāo)準(zhǔn)是可互換的。除 1003.1 之外,1003 和 2003 家族也包括在表中。
表1:標(biāo)準(zhǔn)的重要組成部分
1003.0
管理 POSIX 開(kāi)放式系統(tǒng)環(huán)境(OSE)。IEEE 在 1995 年通過(guò)了這項(xiàng)標(biāo)準(zhǔn)。 ISO 的版本是 ISO/IEC 14252:1996。
1003.1
被廣泛接受、用于源代碼級(jí)別的可移植性標(biāo)準(zhǔn)。1003.1 提供一個(gè)操作系統(tǒng)的 C 語(yǔ)言應(yīng)用編程接口(API)。IEEE 和 ISO 已經(jīng)在 1990 年通過(guò)了這個(gè)標(biāo)準(zhǔn),IEEE 在 1995 年重新修訂了該標(biāo)準(zhǔn)。
1003.1b
一個(gè)用于實(shí)時(shí)編程的標(biāo)準(zhǔn)(以前的 P1003.4 或 POSIX.4)。這個(gè)標(biāo)準(zhǔn)在 1993 年被 IEEE 通過(guò),被合并進(jìn) ISO/IEC 9945-1。
1003.1c
一個(gè)用于線程(在一個(gè)程序中當(dāng)前被執(zhí)行的代碼段)的標(biāo)準(zhǔn)。以前是 P1993.4 或 POSIX.4 的一部分,這個(gè)標(biāo)準(zhǔn)已經(jīng)在 1995 年被 IEEE 通過(guò),歸入 ISO/IEC 9945-1:1996。
1003.1g
一個(gè)關(guān)于協(xié)議獨(dú)立接口的標(biāo)準(zhǔn),該接口可以使一個(gè)應(yīng)用程序通過(guò)網(wǎng)絡(luò)與另一個(gè)應(yīng)用程序通訊。 1996 年,IEEE 通過(guò)了這個(gè)標(biāo)準(zhǔn)。
1003.2
一個(gè)應(yīng)用于 shell 和 工具軟件的標(biāo)準(zhǔn),它們分別是操作系統(tǒng)所必須提供的命令處理器和工具程序。 1992 年 IEEE 通過(guò)了這個(gè)標(biāo)準(zhǔn)。ISO 也已經(jīng)通過(guò)了這個(gè)標(biāo)準(zhǔn)(ISO/IEC 9945-2:1993)。
1003.2d
改進(jìn)的 1003.2 標(biāo)準(zhǔn)。
1003.5
一個(gè)相當(dāng)于 1003.1 的 Ada 語(yǔ)言的 API。在 1992 年,IEEE 通過(guò)了這個(gè)標(biāo)準(zhǔn)。并在 1997 年對(duì)其進(jìn)行了修訂。ISO 也通過(guò)了該標(biāo)準(zhǔn)。
1003.5b
一個(gè)相當(dāng)于 1003.1b(實(shí)時(shí)擴(kuò)展)的 Ada 語(yǔ)言的 API。IEEE 和 ISO 都已經(jīng)通過(guò)了這個(gè)標(biāo)準(zhǔn)。ISO 的標(biāo)準(zhǔn)是 ISO/IEC 14519:1999。
1003.5c
一個(gè)相當(dāng)于 1003.1q(協(xié)議獨(dú)立接口)的 Ada 語(yǔ)言的 API。在 1998 年, IEEE 通過(guò)了這個(gè)標(biāo)準(zhǔn)。ISO 也通過(guò)了這個(gè)標(biāo)準(zhǔn)。
1003.9
一個(gè)相當(dāng)于 1003.1 的 FORTRAN 語(yǔ)言的 API。在 1992 年,IEEE 通過(guò)了這個(gè)標(biāo)準(zhǔn),并于 1997 年對(duì)其再次確認(rèn)。ISO 也已經(jīng)通過(guò)了這個(gè)標(biāo)準(zhǔn)。
1003.10
一個(gè)應(yīng)用于超級(jí)計(jì)算應(yīng)用環(huán)境框架(Application Environment Profile,AEP)的標(biāo)準(zhǔn)。在 1995 年,IEEE 通過(guò)了這個(gè)標(biāo)準(zhǔn)。
1003.13
一個(gè)關(guān)于應(yīng)用環(huán)境框架的標(biāo)準(zhǔn),主要針對(duì)使用 POSIX 接口的實(shí)時(shí)應(yīng)用程序。在 1998 年,IEEE 通過(guò)了這個(gè)標(biāo)準(zhǔn)。
1003.22
一個(gè)針對(duì) POSIX 的關(guān)于安全性框架的指南。
1003.23
一個(gè)針對(duì)用戶組織的指南,主要是為了指導(dǎo)用戶開(kāi)發(fā)和使用支持操作需求的開(kāi)放式系統(tǒng)環(huán)境(OSE)框架
2003
針對(duì)指定和使用是否符合 POSIX 標(biāo)準(zhǔn)的測(cè)試方法,有關(guān)其定義、一般需求和指導(dǎo)方針的一個(gè)標(biāo)準(zhǔn)。在 1997 年,IEEE 通過(guò)了這個(gè)標(biāo)準(zhǔn)。
2003.1
這個(gè)標(biāo)準(zhǔn)規(guī)定了針對(duì) 1003.1 的 POSIX 測(cè)試方法的提供商要提供的一些條件。在 1992 年,IEEE 通過(guò)了這個(gè)標(biāo)準(zhǔn)。
2003.2
一個(gè)定義了被用來(lái)檢查與 IEEE 1003.2(shell 和 工具 API)是否符合的測(cè)試方法的標(biāo)準(zhǔn)。在 1996 年,IEEE 通過(guò)了這個(gè)標(biāo)準(zhǔn)。
除了 1003 和 2003 家族以外,還有幾個(gè)其它的 IEEE 標(biāo)準(zhǔn),例如 1224 和 1228,它們也提供開(kāi)發(fā)可移植應(yīng)用程序的 API。要想得到關(guān)于 IEEE 標(biāo)準(zhǔn)的最新信息,可以訪問(wèn) IEEE 標(biāo)準(zhǔn)的主頁(yè),網(wǎng)址是 http://standards.ieee.org/。有關(guān) POSIX 標(biāo)準(zhǔn)的概述信息,請(qǐng)?jiān)L問(wèn) Web 站點(diǎn) http://standards.ieee.org/reading/ieee/stad_public/description/posix/。
2. Liniux下的線程編程
Linux系統(tǒng)下的多線程遵循POSIX線程接口,稱為pthread。從上面的描述不難知道,POSIX線程接口是POSIX眾多標(biāo)準(zhǔn)中的一個(gè)(POSIX 1003.1-2001)。
編寫(xiě)Linux下的多線程程序,需要使用頭文件pthread.h,連接時(shí)需要使用庫(kù)libpthread.a。順便說(shuō)一下,Linux下pthread的實(shí)現(xiàn)是通過(guò)系統(tǒng)調(diào)用 clone() 來(lái)實(shí)現(xiàn)的。clone() 是Linux所特有的系統(tǒng)調(diào)用,它的使用方式類似fork,關(guān)于 clone() 的詳細(xì)情況,有興趣的讀者可以去查看有關(guān)文檔說(shuō)明。
下面是一個(gè) POSIX 線程的簡(jiǎn)單示例程序(thread1.c):
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

void *thread_function(void *arg) ...{
int i;

for ( i=0; i<20; i++) ...{
printf("Thread says hi! ");
sleep(1);
}
return NULL;
}

int main(void) ...{
pthread_t mythread;

if ( pthread_create( &mythread, NULL, thread_function, NULL) ) ...{
printf("error creating thread.");
abort();
}

if ( pthread_join ( mythread, NULL ) ) ...{
printf("error joining thread.");
abort();
}
exit(0);
}

要編譯這個(gè)程序,只需先將程序存為 thread1.c,然后輸入:
$ gcc thread1.c -o thread1 -lpthread
運(yùn)行則輸入:
$ ./thread1
3. Windows下POSIX線程編程
Windows本身沒(méi)有提供對(duì)POSIX的支持。但有一個(gè)叫 POSIX Threads for Win32 的開(kāi)源項(xiàng)目給出了一個(gè)功能比較完善的Windows下pthreads API的實(shí)現(xiàn)。目前的最新版本是Pthreads-w32 release 2.8.0 (2006-12-22)。
我沒(méi)有測(cè)試過(guò)這個(gè)最新版本,這里只給出2.7.0版的鏈接:ftp://sources.redhat.com/pub/pthreads-win32/pthreads-w32-2-7-0-release.exe。
關(guān)于該開(kāi)源項(xiàng)目的詳細(xì)介紹見(jiàn):http://sources.redhat.com/pthreads-win32/。
3.1 簡(jiǎn)單使用
上面的exe文件是一個(gè)自解壓文件,解壓后,Pre-built.2目錄中有編譯所需要的頭文件(include子目錄)和庫(kù)文件(lib子目錄)。
一個(gè)簡(jiǎn)單的測(cè)試程序(main.cpp):
#include <stdio.h>
#include <pthread.h>
#include <assert.h>

void* Function_t(void* Param)

...{
printf("I am a thread! ");
pthread_t myid = pthread_self();
printf("thread ID=%d ", myid);
return NULL;
}

int main()

...{
pthread_t pid;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_PROCESS);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&pid, &attr, Function_t, NULL);
printf("======================================== ");
getchar();
pthread_attr_destroy(&attr);
return 1;
}
使用 cl.exe 編譯(不熟悉 cl.exe 的請(qǐng)參考:http://blog.csdn.net/liuyongjin1984/archive/2008/01/07/2029405.aspx 或者參見(jiàn)下面3.2部分):
3.2 使用VC++ 6.0或Visual Studio 2005來(lái)運(yùn)行上面的程序
關(guān)鍵有兩點(diǎn):
1. 是將頭文件(include子目錄)和庫(kù)文件(lib子目錄)中的內(nèi)容添加到VC++ 6.0或Visual Studio 2005開(kāi)發(fā)環(huán)境對(duì)應(yīng)的include和lib目錄下。
具體來(lái)說(shuō)(以添加include目錄為例,添加lib目錄類似):
圖1:VC++ 6.0(添加include目錄:工具--》選項(xiàng)--》目錄)
圖2:Visual Studio 2005(添加include目錄:tools--》options)
2. 指定link時(shí)要連接的庫(kù)的名稱(pthreadVC2.lib)
圖3:VC++ 6.0(工程--》設(shè)置--》連接)

圖4:Visual Studio 2005(project-->* property pages)