一 Linux--多線程( 二 )


  • 與線程有關的函數構成了一個完整的系列,絕大多數的名字都是以“pthread_”打頭的 。
  • 使用線程庫需要映入頭文件pthread.h,鏈接這些線程函數是 , 需要指明線程庫名 , 所以編譯時要加上選項-lpthread 。
  • 注意: Linux內核沒有提供線程管理的庫函數 , 這里的線程庫是用戶提供的線程管理功能
    錯誤檢查:
    • 傳統的一些函數是,成功返回0,失敗返回-1,并且對全局變量errno賦值以指示錯誤 。
    • pthreads函數出錯時不會設置全局變量errno(而大部分其他POSIX函數會這樣做,不然這個全局變量就成為臨界資源了) 。而是將錯誤代碼通過返回值返回 。
    • pthreads同樣也提供了線程內的errno變量,以支持其它使用errno的代碼 。對于pthreads函數的錯誤,建議通過返回值判定 , 因為讀取返回值要比讀取線程內的errno變量的開銷更小 。
    線程創建int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);功能:創建一個線程 。參數:    thread:線程標識符地址    attr:線程屬性結構體地址,通常設置為NULL    start_routine:線程函數的入口地址    arg:傳給線程函數的個數返回值:    成功:0    失?。悍?在一個線程中調用pthread_create()創建新的線程之后,當前線程從pthread_create()返回繼續向下運行,而新的線程所執行的代碼由我們傳給pthread_create的函數指針start_routine決定 。
    由于pthread_create的錯誤碼不保存在errno當中,因此不能直接使用perror()打印錯誤信息,可以先用strerror()把錯誤碼轉成錯誤信息再打印 。
    代碼示例:
     #include<stdio.h> #include<stdlib.h> #include<string.h> #include<pthread.h> //線程調度之后執行的任務 void *fun(void *arg) {    printf("新的線程執行任務 tid:%ld\n",pthread_self());    //退出當前函數體    return NULL; }int main(){    int ret = -1;    pthread_t tid = -1;    //創建一個線程    ret = pthread_create(&tid,NULL,fun,NULL);    if(0!=ret)    {      //根據錯誤號打印錯誤信息      printf("error information:%s\n",strerror(ret));      return 1;    }    printf("main thread.....tid:%lud\n",pthread_self());    return 0;}運行結果如下:
    一 Linux--多線程

    文章插圖
    線程在創建過程中不會阻塞 , 主進程會立刻執行,那么存在一個問題 , 主進程如果執行完畢 , 那么所有線程都將被釋放,就可能出現線程還未調度的問題 。(后面會解決)
    線程和進程有區別,父子進程執行的代碼段是一樣的,但是線程被創建之后執行的是線程處理函數 。
    再介紹一個函數:
    就像每個進程都有一個進程號一樣,每個線程也有一個線程號 。進程號再整個系統中是唯一的,但是線程號不同,線程號只在它所屬的進程環境中有效 。
    進程號用pid_t數據類型表示,是一個非負整數 。線程號則用pthread_t數據類型來表示,Linux使用無符號長整型數表示 。
    實例1: 創建一個線程,觀察代碼運行效果和函數用法
    pthread_t pthread_self(void);功能:獲取線程號參數:無返回值:調用線程的線程ID#include <stdio.h>#include <pthread.h>#include <unistd.h>void* pthreadrun(void* arg){ char* name = (char*)arg; while (1){printf("%s is running...\n", name);sleep(1); }}int main(){ pthread_t pthread; // 創建新線程 pthread_create(&pthread, NULL, pthreadrun, (void*)"new thread"); while (1){printf("main thread is running...\n");sleep(1); } return 0;}運行結果如下:
    一 Linux--多線程

    文章插圖
    實例2: 創建4個線程,然后打印出各自的pid和線程id
    #include <stdio.h>#include <pthread.h>#include <unistd.h>void* pthreadrun(void* arg){  long id = (long)arg;  while (1){    printf("threaad %ld is running, pid is %d, thread id is %p\n", id, getpid(), pthread_self());    sleep(1);  }}int main(){  pthread_t pthread[5];  int i = 0;  for (; i < 5; ++i)  {    // 創建新線程    pthread_create(pthread+i, NULL, pthreadrun, (void*)i);  }  while (1){    printf("main thread is running, pid is %d, thread id is %p\n", getpid(), pthread_self());    sleep(1);  }  return 0;}

    推薦閱讀