原文: http://csynine.blog.51cto.com/1388509/310927
對於這個問題,網上已經有很多資料給予了介紹,但是相比於這些信息,本文立足於個人的實踐,將內容具體到開發環境和源代碼,我覺得還是有很多值得總結和借鑑的。
首先聲明開發環境。Win32程序的開發環境是VS.Net 2008,編程語言是C;Linux使用的RHEL 5.4,GCC的版本是4.1.2,編程語言也是C。
然後依次說明移植的對象:數據類型/字符串處理/系統調用/套接字/進程/進程鎖/線程/線程鎖/信號量/事件鎖/條件鎖/系統服務。
1. 數據類型:在開發過程中,無論哪種平臺,只使用最通用的數據類型char,unsigned char,int,unsigned int,void *以及它們組合的結構體類型。對於數據長度敏感的代碼,則只使用下面的數據類型:
Common |
Win32 |
Linux |
int8 |
INT8 |
int8_t |
uint8 |
UINT8 |
uint8_t |
int16 |
INT16 |
int16_t |
uint16 |
UINT16 |
uint16_t |
int32 |
INT32 |
int32_t |
uint32 |
UINT32 |
uint32_t |
int64 |
INT64 |
int64_t |
uint64 |
UINT64 |
uint64_t |
在VS.Net 2008的項目中,使用多字節字符集,對於需要寬字符的系統調用,使用字節轉換函數來處理參數。
2. 字符串處理:雖然每個函數在兩個平臺下都有對應的實現,但是最好自己重新實現,因爲它們都不足夠令人滿意:
Common |
Win32 |
Linux |
stricmp_x |
_stricmp |
strcasecmp |
strtok_x |
strtok_s |
strtok_r |
sprintf_x |
sprintf_s |
snprintf |
vsprintf_x |
vsprintf_s |
vsnprintf |
strcpy_x |
strcpy_s |
strncpy |
strcat_x |
strcat_s |
strncat |
3. 系統調用:真正的系統調用雖然不多,只有僅有的幾十個,但有些系統調用差別很大,這裏就不便做一一贅述了,而有些系統調用基本沒有差別,比如文件相關的操作。
4. 套接字:套接字的幾個主要函數都一樣,socket/bind/listen/connect/accept/select/send/recv,幾個細微的差別在於Win32使用套接字運行TCP/IP協議需要初始化上下文環境,另外,對於套接字定義,Win32使用SOCKET,Linux使用int,對於關閉套接字,Win32使用closesocket,Linux使用close。
5. 進程:在Windows平臺中使用CreateProcess來創建進程,子進程返回句柄和ID給父進程,在Linux平臺中使用fork和execv來創建進程,子進程返回ID給父進程。兩者最大的差別在於,在Windows平臺中子進程跟父進程沒有任何關係,而在Linux平臺中,子進程繼承了父進程的進程上下文環境。其它相關函數的差別如下:
Win32 |
Linux |
CreateProcess |
fork/execv |
TerminateProcess |
kill |
ExitProcess |
exit |
GetCommandLine |
argv |
GetCurrentProcessId |
getpid |
KillTimer |
alarm |
SetEnvironmentVariable |
putenv |
GetEnvironmentVariable |
getenv |
GetExitCodeProcess |
waitpid |
6. 進程鎖:是指多個進程同步的機制。多進程同步的方法有很多,比如共享內存,命名信號量等。這裏只說明一下命名信號量的機制,共享內存的方法可以查閱相關手冊。Win32比較簡單,在CreateMutex的參數中輸入相應名稱即可,Linux中,則可使用System V IPC的semget/semctl/semop操作,具體步驟直接man之。
7. 線程:線程同步、等待函數、線程本地存儲以及初始化和終止抽象是線程模型的重要部分。主要對應函數列表如下:
Win32 |
Linux |
_beginthreadex |
pthread_create |
_endthreadex |
pthread_exit |
TerminateThread |
pthread_cancel |
GetCurrentThreadId |
pthread_self |
8. 線程鎖:對應函數列表如下。另外,特別注意的是,Win32的mutex在缺省情況下是可以遞歸加鎖和解鎖的,但是pthread的mutex在缺省情況下則不能,需要在pthread_mutex_init時設置pthread_mutexattr_t參數。
Win32 |
Linux |
CreateMutex |
pthread_mutex_init |
CloseHandle |
pthread_mutex_destroy |
WaitForSingleObject |
pthread_mutex_lock |
ReleaseMutex |
pthread_mutex_unlock |
9. 信號量/事件鎖/條件鎖:這三個同步機制功能比較相似,甚至可以相互實現。除了這三種同步機制外,各個平臺上還有一些專有的同步機制。Windows平臺上有信號量和事件鎖,但是沒有條件鎖,直到Windows 2008 Server上纔會有。Linux平臺上有信號量和條件鎖,但是沒有事件鎖。在一些特定場合下,沒有的同步機制只能通過已有的同步機制去實現:
Common |
Win32 |
Linux |
Semaphore |
CreateSemaphore |
pthread_mutex_init |
Event |
CreateEvent |
pthread_mutex_init |
Condition |
CreateSemaphore |
pthread_cond_init |
10. 系統服務:在Windows中,系統服務叫service,可以通過管理工具,或者運行services.msc進入管理界面,可以安裝,卸載,啓動,停止和重啓。在Linux中,系統服務叫daemon,一般通過命令service ??? start/stop/restart來啓動,停止和重啓,同樣也可以安裝和卸載。Windows服務可以通過SCM(Service Control Management)架構來實現,Linux服務則需要編寫chkconfig相關的腳本來實現。注意,不同的Linux發行版,比如RHEL和SLES,實現腳本是不一樣的。