一直以來,由於標準C++中沒有納入線程庫,對於多線程的編程感到束手無策,win32的線程機制感覺用着不便。今天想搜索一下有沒有其他線程庫,想到了Unix下隨處可見的pthread線程庫,但是苦於這個庫是針對unix系統設計的,無法拿到VS中使用。Google了一下,竟然有win32版的pthread,心中大快。趕緊下來使用了一下,當真可行,故分享之。
下載
建議大家下載:
ftp://sources.redhat.com/pub/pthreads-win32/pthreads-w32-2-7-0-release.exe這個自解壓文件,壓縮包裏的pthreads.2目錄是源碼,Pre-built.2目錄是編譯所需的頭文件和庫文件。
如果要自行編譯請看這裏:
使用微軟的CL來編譯:
rem cl.bat
cl.exe main.cpp /c /I"c:/pthreads-w32-2-7-0-release/Pre-built.2/include"
link.exe /out:main_cl.exe main.obj /LIBPATH:"c:/pthreads-w32-2-7-0-release/Pre-built.2/lib" pthreadVC2.lib
pause
或者使用GCC來編譯:
rem gcc.bat
g++.exe -o main.o -c main.cpp -I"c:/pthreads-w32-2-7-0-release/Pre-built.2/include"
g++.exe -o main_gcc.exe main.o "c:/pthreads-w32-2-7-0-release/Pre-built.2/lib/libpthreadGC2.a"
pause
嘿嘿!開源就是好啊,跨平臺實現得如此容易
使用
建好工程後。
VS-工具-選項-項目和解決方案-VC++目錄,右邊引用文件添加目錄***/include,庫文件添加目錄***/lib
下面①②選一種就可以
①然後在include pthread之後加句
#pragma comment(lib, "pthreadVC2.lib")
②或者在項目-屬性-配置屬性-鏈接器-常規-附加庫目錄,加進庫目錄
在項目-屬性-配置屬性-鏈接器-輸入-附加依賴項,加進lib庫名
最後在windows/system32裏複製進pthreadVC2.dll。這文件在Pre-built.2裏有。然後編譯就ok了。
OK!現在寫一個簡單的pthread來測試:
#include <stdio.h>
#include <pthread.h>
#include <assert.h>
void* Function_t(void* Param)
{
printf("我是線程! ");
pthread_t myid = pthread_self();
printf("線程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;
}
pthread相關介紹
參數tid用於返回新創建線程的線程號;start_routine是線程函數指針,線程從這個函數開始運行;arg是傳遞給線程函數的參數。由於start_routine是一個指向參數類型爲void*,返回值爲void*的指針,所以如果需要傳遞或返回多個參數時,可以使用強制類型轉化。
void pthread_exit(void* value_ptr);
參數value_ptr是一個指向返回狀態值的指針。
int pthread_join( pthread_t tid, void **status);
參數tid是希望等待的線程的線程號,status是指向線程返回值的指針,線程的返回值就是pthread_exit中的value_ptr參數,或者是return語句中的返回值,該函數可用於線程間的同步。
int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex_attr_t* attr);
該函數初始化一個互斥變量,如果參數attr爲NULL,則互斥體變量mutex使用默認的屬性。
int pthread_mutex_lock(pthread_mutex_t *mutex);
該函數用來鎖住互斥體變量,如果參數mutex所指的互斥體已經被鎖住了,那麼發出調用的線程將被阻塞直到其他線程對mutex解鎖。
int pthread_mutex_trylock(pthread_t *mutex);
該函數用來鎖住mutex所指定的互斥體,但不阻塞。如果該互斥體已經被上鎖,該調用不會阻塞等待,而會返回一個錯誤代碼。
int pthread_mutex_unlock(pthread_mutex_t *mutex);
該函數用來對一個互斥體解鎖。如果當前線程擁有參數mutex所指定的互斥體,該調用將該互斥解鎖。
int pthread_mutex_destroy(pthread_mutex_t *mutex);
該函數用來釋放分配給參數mutex的資源。調用成功時返回值爲0,否則返回一個非0的錯誤代碼。
int pthread_cond_int(pthread_cond_t *cond,const pthread_cond_attr_t *attr);
該函數按參數attr指定的屬性創建一個條件變量。調用成功返回,並將條件變量ID賦值給參數cond,否則返回錯誤代碼。
int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);
該函數調用爲參數mutex指定的互斥體解鎖,等待一個事件(由參數cond指定的條件變量)發生。調用函數的線程被阻塞直到有其他線程調用pthread_cond_signal或pthread_cond_broadcast函數置相應的條件變量,而且獲得mutex互斥時才解除阻塞。
int pthread_cond_timewait(pthread_cond_t *cond,pthread_mutex_t *mutex,const struct timespec *abstime);
該函數與pthread_cond_wait不同的是當系統時間到達abstime參數指定的時間時,被阻塞線程也可以被喚起繼續執行。
int pthread_cond_broadcast(pthread_cond_t *cond);
該函數用來對所有等待參數cond所指定的條件變量的線程解除阻塞,調用成功返回0,否則爲錯誤代碼。
int pthread_cond_signal(pthread_cond_t *cond);
該函數的作用是解除一個等待參數cond所指定的條件變量,也只喚醒一個線程。
int pthread_cond_destroy(pthread_cond_t *cond);
該函數釋放一個條件變量。釋放爲條件變量cond所分配的資源。調用成功返回值爲0,否則爲錯誤代碼。
int pthread_key_create(pthread_key_t key,void(*destructor(void*)));
該函數創建一個鍵值,該鍵值映射到一個專有數據結構體上。如果第二個參數不是NULL,這個鍵值被刪除時將調用這個函數指針來釋放數據空間。
int pthread_key_delete(pthread_key_t *key);
該函數用於刪除一個由pthread_key_create函數調用創建的TSD鍵。調用成功返回值0,否則爲返回錯誤代碼。
int pthread_setspecific(pthread_key_t key,const void(value));
該函數設置一個線程專有數據的值,賦給由pthread_key_create創建的TSD鍵,調用成功返回值爲0,否則返回錯誤代碼。
void* pthread_getspecific(pthread_key_t *key);
該函數獲得綁定到指定的TSD鍵上的值。調用成功,返回給定參數key所對應的數據。如果沒有數據連接到該TSD鍵,則返回NULL。
int pthread_once(pthread_once_t* once_control,void(*int_routine)(void));
該函數的作用是確保init_routine指向的函數,在調用pthread_once的線程中只被運行一次。once_control指向一個靜態或全局的變量。