線程的創建
線程庫的頭文件包含在頭文件pthread.h中:
線程創建函數:int pthread_create(pthread_t *id,pthread_attr_t* attr,void*(*pthread_fun)(void*),void* arg);
pthread_fun函數是一個線程函數,即新創建的線程的執行體。pthread_create函數會創建出一條新的函數線程,線程從pthread_fun函數入口地址開始執行,到pthread_fun函數結束。參數中的id是線程創建時分配的線程id,應該傳一個變量的地址將id值帶出。arg參數爲給pthread_fun函數傳遞的參數。attr爲線程屬性,默認爲NULL。pthread_create函數成功返回0,失敗返回錯誤碼。該函數一般不會阻塞。
線程結束函數:void pthread_exit(void*);
主線程結束默認調用exit函數,這個函數會結束進程。進程結束,所有的線程也會隨之結束。
等待線程結束函數:int pthread_join(pthread_t id,void**);
該函數會阻塞,直到等待的線程結束。
終止一個線程:int pthread_cancel(pthread_t id);
該函數只是發起取消請求,並不會阻塞。
創建線程時給函數線程傳參的兩種方式
1.值傳遞
最多傳遞4字節的數據,將傳遞的值直接強轉爲void*,記錄的是傳遞的值。
void* fun(void* arg)
{
int data = (int)arg;
}
int main()
{
int data = 10;
pthread_t id;
int res = pthread_create(&id,NULL,fun,(void*)arg);
assert(0 == res);
return 0;
}
2.地址傳遞
將要傳遞的值的地址轉化爲void*,記錄的是傳遞的值的地址。
void* fun(void* arg)
{
int data = *(int *)arg;
}
int main()
{
int data = 10;
pthread_t id;
int res = pthread_create(&id,NULL,fun,(void *)&data);
assert(0 == res);
return 0;
}
地址傳遞時函數線程中通過形參傳遞的地址對變量進行修改,會影響主線程中變量的值。同時主線程中對變量的修改,也會影響函數線程中變量的值。這也驗證了同一進程中所有線程共享4G虛擬地址空間。
多線程的數據共享
由於線程是進程中的一條執行序列,所以一個進程中的所有線程共享全局、堆區數據,包括打開的文件描述符。只有棧區的數據是每個線程獨享的。