歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> 關於Linux >> 關於Linux下的多線程

關於Linux下的多線程

日期:2017/3/3 17:05:15   编辑:關於Linux

 一、線程的創建

  頭文件

  #include <pthread.h>

  函數聲明

  int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

  在一個線程中調用pthread_create函數創建新的線程後,當前線程從pthread_create處繼續往下執行,start_routine為新創建線程的入口函數,start_routine函數接收一個參數,是通過pthread_create的arg參數傳遞給它的,該參數的類型為void* ,這個指針按什麼類型解釋由調用者自己定義,start_routine的返回值類型也是void,這個指針的含義同樣由調用者自己定義,start_routine返回時,這個線程就退出了,其它線程可以調用pthread_join得到start_routine的返回值。

  參數說明

  第一個參數為指向線程標識符的指針。

  第二個參數用來設置線程屬性,用於指定各種不同的線程屬性。

  第三個參數是線程運行函數的起始地址,該函數只有一個萬能指針參數arg,如果需要向start_rtn函數傳遞的參數不止一個,那麼需要把這些參數放到一個結構中,然後把這個結構的地址作為arg的參數傳入。

  最後一個參數是運行函數的參數。

  返回值

  若線程創建成功,則返回0,若線程創建失敗,則返回出錯編號,並且*thread中的內容是未定義的。

  第一個簡單的線程程序

  #include <stdio.h>

  #include <pthread.h>

  void printThread(const char *s)

  {

  pid_t pid;

  pthread_t tid;

  pid = getpid();

  tid = pthread_self();

  printf("%s pid %u tid %u (0x%x)\n", s, (unsigned int) pid, (unsigned int) tid, (unsigned int) tid);

  }

  void* run(void* arg)

  {

  printThread("new thread: ");

  return NULL;

  }

  int main(void)

  {

  pthread_t pt;

  int err = pthread_create(&pt, NULL, run, NULL);

  if (err != 0)

  printf("can't create thread: %s\n", strerror(err));

  printThread("main thread:");

  pthread_join(pt, NULL);

  return 0;

  }

  注意

  因為pthread並非Linux系統的默認庫,而是POSIX線程庫。在Linux中將其作為一個庫來使用,因此加上 -lpthread(或-pthread)以顯式鏈接該庫。

  $g++ main.cpp -lpthread -o main

  $./main

  二、pthread_join函數

  函數聲明

  int pthread_join(pthread_t thread, void **retval);

  參數說明

  thread: 線程標識符,即線程ID,標識唯一線程。

  retval: 用戶定義的指針,用來存儲被等待線程的返回值。

  描述

  pthread_join函數,阻塞當前線程的執行,以等待thread指定的線程結束。當函數返回時,被等待線程的資源被收回。如果進程已經結束,那麼該函數會立即返回。並且thread指定的線程必須是joinable的,新創建的線程默認就是joinable的。


 三、線程的兩種狀態:joinable(默認)和detached

  joinable線程可以被其他線程回收,在被其他線程回收之前,它所占用的存儲器資源並不被釋放,而detached線程不能被其他線程回收,它占用的存儲器資源由系統自動釋放。

  在默認情況下,線程是joinable的,只有當pthread_join函數返回時,創建的線程才算終止,才能釋放自己占用的系統資源,而detached線程沒有被其他線程等待,線程執行完畢立馬釋放系統資源。

  設置線程狀態的函數pthread_attr_setdetachstate,函數聲明為pthread_attr_setdetachstate(pthread_attr_t* attr, int detachstate);其中第二個參數是可選的PTHREAD_CREATE_DETACHED(分離線程)和 PTHREAD _CREATE_JOINABLE(非分離線程)。

  如果設置一個線程為分離線程,而這個線程運行又非常快,它很可能在pthread_create函數返回之前就終止了,它終止以後就可能將線程號和系統資源移交給其他的線程使用,這樣調用pthread_create的線程就得到了錯誤的線程號。要避免這種情況可以采取一定的同步措施,最簡單的方法之一是可以在被創建的線程裡調用pthread_cond_timewait函數,讓這個線程等待一會兒,留出足夠的時間讓函數pthread_create返回。設置一段等待時間,是在多線程編程裡常用的方法。但是注意不要使用諸如 wait 之類的函數,它們是使整個進程睡眠,並不能解決線程同步的問題。

  如果進程中的某個線程執行了pthread_detach(th),則th線程將處於DETACHED狀態,這使得th線程在結束運行時自行釋放所占用的內存資源,同時也無法由pthread_join()同步,pthread_detach()執行之後,對th請求pthread_join()將返回錯誤。

  四、linux下多線程屬性設置

  attr的缺省屬性值

  pthread_attr_t attr;

  初始化屬性

  pthread_attr_t attr;

  pthread_attr_init(&attr);

  pthread_attr_init 成功完成後將返回0,其他任何返回值都表示出現了錯誤,並將返回對應的值。

  銷毀屬性

  使用 pthread_attr_destroy(&attr) 刪除初始化期間分配的存儲空間,屬性對象將會無效,函數成功完成後將返回0,其他任何返回值都表示出現了錯誤,並將返回對應的值。

Copyright © Linux教程網 All Rights Reserved