Linux 多線程/進程通信同步: 信號量
線程是程序中完成一個獨立任務的完整執行序列,即一個可調度的實體。根據運行環境的調度這的身份,線程可分為內核線程和用戶線程。內核線程,在有的系統上稱為LWP(Light Weight Process,輕量級線程),運行在內核空間,由內核調度;用戶線程運行在用戶空間,由線程庫來調度。當進程的一個內核線程獲得CPU的使用權時,它就加載并運行一個用戶線程。可見,內核線程相當于用戶線程運行的‘容器’,一個進程可以擁有M個內核線程和N個用戶線程,其中M<=N,并且一個系統的所有進程中,M和N的比值是固定的。
進程中的不同線程不像不同進程之間那樣存在很大的獨立性,所有的線程有完全一樣的地址空間,這意味著他們也共享同樣的全局變量。除了共享地址空間外,所有的線程還共享同一個打開文件集、子進程以及相關信號等,每個線程有自己的堆棧。
在多線程的情況下,進程通常會從當前的單個線程開始,這個線程有能力通過調用一個庫函數(如pthread_create)創建新的線程,thread_create函數的參數指定了要運行的函數名。
線程控制函數
線程創建 pthread_create
#include
int pthread_create(pthread_t * tidp, const pthread_attr_t *attr, void *(*start_rtn)(void *), void *arg);
返回:成功返回0,出錯返回錯誤編號
當pthread_create函數返回成功時,有tidp指向的內存被設置為新創建線程的線程ID,其類型pthread_t定義為
#include
typedef unsigned long int pthread_t;
attr參數用于定制各種不同的線程屬性,為NULL時表示默認線程屬性。新創建的線程從start_rtn函數的地址開始運行,該函數只有一個無類型指針的參數arg,如果需要向start_rtn函數傳入的參數不止一個,可以把參數放入到一個結構中,然后把這個結構的地址作為arg的參數傳入。
線程創建時并不能保證哪個線程會先運行:是新創建的線程還是調用線程。新創建的線程可以訪問調用進程的地址空間,并且繼承調用線程的浮點環境和信號屏蔽字,但是該線程的未決信號集被清除。
線程終止 pthread_exit
#include
void pthread_exit(void *rval_ptr);
線程在結束時最好調用該函數,以確保安全、干凈的退出。pthread_exit函數通過rval_ptr參數向調用線程的回收者傳遞退出信息,進程中的其他線程可以調用pthread_join函數訪問到這個指針。pthread_exit執行完后不會返回到調用者,而且永遠不會失敗。
線程可以通過以下三種方式退出,在不終止整個進程的情況下停止它的控制流:
l ?線程只是從啟動歷程中退出,返回值是線程的退出碼
l ?線程可以被同一進程中的其他線程取消
l ?線程調用pthread_exit
pthread_join
#include
int pthread_join(pthread_t thread, void **rval_ptr);
返回:成功返回0,出錯返回錯誤代碼
thread是目標線程標識符,rval_ptr指向目標線程返回時的退出信息,該函數會一直阻塞,直到被回收的線程結束為止。可能的錯誤碼為:
取消線程 pthread_cancel
#include
int pthread_cancel(pthread_t thread);
返回:成功返回0,出錯返回錯誤代碼
默認情況下,pthread_cancel函數會使有thread標識的線程的表現為如同調用了參數為PTHREAD_CANCEL的pthread_exit函數,但是,接收到取消請求的目標線程可以決定是否允許被取消以及如何取消,者分別由一下兩個函數來控制
#include
int pthread_setcancelstate(int state, int *oldstate);
int pthread_setcanceltype(int type, int *oldstate);
注意pthread_cancel并不等待線程結束,它只是提出請求。
創建線程簡單示例:
#include
#include
#include
#define err_sys(msg) \
do { perror(msg); exit(-1); } while(0)
#define err_exit(msg) \
do { fprintf(stderr, msg); exit(-1); } while(0)
void *thread_func(void *arg)
{
printf("hello world!\n");
sleep(1);
pthread_exit("hdu");
}
int main(void)
{
pthread_t tid;
char* p = NULL;
pthread_create(&tid, NULL, thread_func, NULL);
pthread_join(tid, (void **)&p);
printf("message: %s\n", p);
return 0;
}
linux 任務調度 多線程
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。