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

要編譯這個程序,只需先將程序存為 thread1.c,然后輸入:
$ gcc thread1.c -o thread1 -lpthread
運行則輸入:
$ ./thread1
3. Windows下POSIX線程編程
Windows本身沒有提供對POSIX的支持。但有一個叫 POSIX Threads for Win32 的開源項目給出了一個功能比較完善的Windows下pthreads API的實現。目前的最新版本是Pthreads-w32 release 2.8.0 (2006-12-22)。
我沒有測試過這個最新版本,這里只給出2.7.0版的鏈接:ftp://sources.redhat.com/pub/pthreads-win32/pthreads-w32-2-7-0-release.exe。
關于該開源項目的詳細介紹見:http://sources.redhat.com/pthreads-win32/。
3.1 簡單使用
上面的exe文件是一個自解壓文件,解壓后,Pre-built.2目錄中有編譯所需要的頭文件(include子目錄)和庫文件(lib子目錄)。
一個簡單的測試程序(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 的請參考:http://blog.csdn.net/liuyongjin1984/archive/2008/01/07/2029405.aspx 或者參見下面3.2部分):
3.2 使用VC++ 6.0或Visual Studio 2005來運行上面的程序
關鍵有兩點:
1. 是將頭文件(include子目錄)和庫文件(lib子目錄)中的內容添加到VC++ 6.0或Visual Studio 2005開發環境對應的include和lib目錄下。
具體來說(以添加include目錄為例,添加lib目錄類似):
圖1:VC++ 6.0(添加include目錄:工具--》選項--》目錄)
圖2:Visual Studio 2005(添加include目錄:tools--》options)
2. 指定link時要連接的庫的名稱(pthreadVC2.lib)
圖3:VC++ 6.0(工程--》設置--》連接)

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