日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

线程以及pthread库的使用

發布時間:2023/12/9 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 线程以及pthread库的使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

https://blog.csdn.net/weixin_38102771/article/details/91351126
https://blog.csdn.net/qq_29677867/article/details/108571388?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_baidulandingword-0&spm=1001.2101.3001.4242
一.什么是線程
你可以想象你一邊聽歌一邊打游戲,如果是操作系統會怎么做呢?先執行 ListenMusic 再執行 PlayGame,還是先執行 PlayGame 再執行 ListenMusic 呢?好像都不太合適。為了實現這個目的,就需要引入線程這個概念。線程是 CPU 調度的最小執行單位,你可以創建一個線程用于 ListenMusic,再創建一個線程去 PlayGame,這樣操作系統就是同時處理這兩個任務的(并發)。

二.pthread庫
(1) 使用說明
POSIX 標準定義了一套線程操作相關的函數,用于讓程序員更加方便地操作管理線程,函數名都是以前綴 pthread_ 開始,使用時要包含 <pthread.h>,而且在鏈接的時候要手動鏈接 pthread 這個庫,如:gcc main.c -lpthread -o main。

(2) 常用函數

  • pthread_create
    函數原型:int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
  • 功能說明:創建一個線程。

    參數說明

    thread:線程句柄,需要先定義一個 pthread_t 類型變量 thread,將該變量的地址 &thread 傳遞到該參數中去。這是一個傳出參數,傳遞進去的 thread 會得到系統為我們創建好的線程句柄。

    attr:線程屬性,通過該參數可以設置創建的線程屬性,如果要使用默認屬性直接傳遞 NULL 即可。

    start_routine:線程函數,它是一個函數指針類型,返回類型為 void *,參數為一個 void * 類型變量,創建好這樣類型的一個函數,將函數名傳遞進去即可。

    arg:線程參數,代表需要在主線程傳遞給子線程的參數,給 arg 賦值后可以在線程函數的參數中取到。

    返回值說明

    成功情況下返回 0,失敗情況下返回錯誤碼,并且 tid 的值是不確定的。Linux 環境下所有線程函數調用失敗時均是返回錯誤碼,除了部分返回值為 void 的函數。關于錯誤碼的說明在這里的第 8 小節。
  • pthread_self
    函數原型:pthread_t pthread_self(void);
  • 功能說明:獲取線程 ID。

    參數說明:無參數。

    返回值說明:如果在主線程中調用該函數會返回主線程的線程 ID,如果在子線程中調用該函數會返回子線程的線程 ID,該函數沒有失敗的情況。

    額外說明:線程 ID 是進程內部識別標志,兩個進程間線程 ID 允許相同。

  • pthread_equal
    函數原型:int pthread_equal(pthread_t t1, pthread_t t2);
  • 功能說明:比較兩個線程 ID 是否相等,在 Linux 系統中 pthread_t 都設計為 unsigned long 類型,所以可以直接用 == 判別是否相等,但是如果某些系統設計為結構體類型,那么就可以通過 pthread_equal 函數判別是否相等了。

    參數說明:要比較的兩個線程 ID。

    返回值說明:若相等返回非 0 數值,否則返回 0。

  • pthread_exit
    函數原型:void pthread_exit(void *retval);
  • 功能說明:將單個線程退出。

    參數說明:retval 為該線程的返回狀態,如果主線程調用 pthread_join 可以獲取到該返回狀態。

    返回值說明:void。

    額外說明:如果在主線程中調用了 pthread_exit(NULL),則主線程退出,如果子線程存在會繼續執行。如下代碼,就算主線程先退出了,也不會影響子線程打印"我是子線程"。注意如果使用 exit 退出會導致整個進程結束。

  • pthread_join
    函數原型:int pthread_join(pthread_t thread,void **retval);
  • 功能說明:阻塞等待線程退出,獲取線程退出狀態,相當于進程中的 waitpid 函數,如果線程退出,pthread_join 立刻返回。

    參數說明

    thread:代表要等待線程的線程 ID

    retval:獲取該線程的退出狀態

    返回值說明

    成功情況下返回 0,失敗則返回錯誤碼。
  • pthread_detach
    函數原型:int pthread_detach(pthread_t thread);
  • 功能說明:將線程 ID 為 thread 的線程分離出去,所謂分離出去就是指主線程不需要再通過 pthread_join 等方式等待該線程的結束并回收其線程控制塊(TCB)的資源,被分離的線程結束后由操作系統負責其資源的回收。

    參數說明:thread 為要分離的線程的線程 ID。

    返回值說明

    成功情況下返回 0,失敗情況下返回錯誤碼。

    額外說明

    一般來說,主線程是要負責創建出來的子線程的資源回收工作的。如果主線程先于子線程退出并且子線程沒有設置為分離狀態,那么子線程結束后其資源是無法得到回收的,會造成資源浪費和系統臃腫;如果主線程先于子線程退出但是子線程時分離狀態,那么子線程退出的時候操作系統會自動回收其資源。
  • pthread_cancel
    函數原型:int pthread_cancel(pthread_t thread);
  • 功能說明:殺死線程。

    參數說明:thread 為要殺死的線程的線程 ID。

    返回值說明:成功情況下返回 0,失敗情況下返回錯誤碼。

    程序說明

    分別創建了兩個線程,pthread_func3 是一個死循環。在主線程中 sleep(3) 之后調用 pthread_cancel 結束子線程 pthread_func3,再調用 pthread_join 回收該子線程,由于子線程已經被殺死,此時 pthread_join 返回 -1。如果在子線程中的 while(1) 里,將 printf 和 sleep 函數注釋掉,會發現殺不死該線程,原因是 pthread_cancel 并不等待線程終止,它僅僅提出了一種請求,需要子線程執行到特定的取消點才能終止該線程(如一些系統調用 write,pause 等地方)。如果線程中沒有系統調用的函數,可以加入 pthread_testcancel 函數作為取消點。
  • 常見錯誤碼
    EDEADLK:檢測到線程發生死鎖
  • EINVAL:線程不是可以等待回收的線程(后續會講到線程分離)或者有其他線程已經準備等待回收該線程了

    ESRCH:該線程 ID 不存在

    三.使用線程的好處
    在 Linux 編程中,多線程編程無疑是十分重要的。它可以提高程序的并發處理能力,線程間通信和共享數據十分方便,而且相對于多進程來說,它更加輕量級、好用。
    ————————————————
    版權聲明:本文為CSDN博主「夢別停」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
    原文鏈接:https://blog.csdn.net/weixin_38102771/article/details/91351126

    總結

    以上是生活随笔為你收集整理的线程以及pthread库的使用的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。