Linux筆記---線程控制

1. 線程創建:pthread_create()

pthread_create()?是 POSIX 線程庫(pthread)中用于創建新線程的函數。調用該函數后系統就會啟動一個與主線程并發的線程,并使其跳轉到入口函數處執行。

#include <pthread.h>int pthread_create(pthread_t *thread,          // 指向線程標識符的指針const pthread_attr_t *attr, // 線程屬性(通常設為 NULL 使用默認值)void *(*start_routine)(void*), // 線程執行的函數void *arg                   // 傳遞給線程函數的參數
);

參數說明:?

  1. pthread_t* thread:輸出型參數,存儲新創建線程的標識符(線程 ID)。
  2. const pthread_attr_t* attr:設置線程的屬性(如棧大小、調度策略等)。 常用值:NULL(使用默認屬性)。?
  3. void* (*)(void*) start_routine:新線程啟動后執行的函數(線程入口點)。 要求:必須返回 void*,且接受一個 void* 參數。
  4. void* arg:傳遞給 start_routine 的參數。 注意:若無需參數,可傳 NULL;若需傳遞多個參數,可封裝為結構體。

返回值:?

  • 成功:返回 0。
  • 失敗:返回錯誤碼(如 EAGAIN、EINVAL 等),但不設置 errno。

示例代碼:?

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <pthread.h>
using namespace std;void* start_routine(void* arg)
{cout << "start_routine: 線程創建成功" << endl;return nullptr;
}int main()
{pthread_t tid;int n = pthread_create(&tid, nullptr, start_routine, nullptr);if(n != 0){cout << "線程創建失敗: " << strerror(n) << endl;}while(true);return 0;
}


2. 線程等待:pthread_join()

pthread_join() 是 POSIX 線程庫中用于等待線程結束并回收其資源的函數。

主線程如何取得線程運行結束的返回值呢?我們可以使用pthread_join()函數來對指定線程進行等待,并獲取其返回值。和waitpid()函數一樣,調用這個函數會使主線程阻塞在調用處直到被等待的指定線程運行結束

和多進程編程一樣,線程如果不進行等待回收,那么其就會一直保留其運行結果等信息,造成內存泄漏。除此之外,與多進程編程不一樣的是,一個進程的多個線程共享主線程的地址空間,一旦主線程退出,其創建的所有線程都會被強制終止,無論其是否執行完

所以在上面的例子當中,線程啟動之后我們讓主線程陷入了死循環當中,避免其提前退出。

#include <pthread.h>int pthread_join(pthread_t thread,     // 要等待的線程 IDvoid **retval         // 指向線程返回值的指針(可選)
);

核心功能:

  • 阻塞等待:調用 pthread_join() 的線程會暫停執行,直到目標線程終止。
  • 資源回收:線程終止后,其占用的系統資源(如線程描述符、棧空間)會被釋放。 若不調用 pthread_join(),終止的線程會成為 “僵尸線程”,造成資源泄漏。
  • 獲取返回值:通過 retval 參數獲取目標線程的返回值(start_routine 的返回值或 pthread_exit() 的參數)。?

參數說明:

  1. pthread_t thread:指定要等待的線程 ID(由 pthread_create() 返回)。
  2. void** retval:輸出型參數,存儲線程的返回值(即線程函數 start_routine 的返回值)。 若無需獲取返回值,可傳 NULL。

?返回值:

  • 成功:返回 0。
  • 失敗:返回錯誤碼(如 EDEADLK、ESRCH 等)。

示例代碼:

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <pthread.h>
using namespace std;void* start_routine(void* arg)
{cout << "start_routine: 線程創建成功" << endl;for(int i = 0; i < 5; i++){cout << "計數----->" << i << endl;sleep(1);}return (void*)10;
}int main()
{pthread_t tid;int n = pthread_create(&tid, nullptr, start_routine, nullptr);if(n != 0){cout << "線程創建失敗: " << strerror(n) << endl;}int result;int m = pthread_join(tid, (void**)&result);if(m != 0){cout << "線程等待失敗: " << strerror(m) << endl; }cout << "線程的返回值為: " << result << endl;return 0;
}


3. 線程終止

除主線程以外,線程的正常終止有三種情況:

  1. 從入口函數的return處返回
  2. 調用pthread_exit()函數退出(調用exit()函數會導致整個進程退出)
  3. 某個線程調用pthread_cancel()來終止指定線程

?3.1 pthread_exit()

#include <pthread.h>void pthread_exit(void *retval);  // 無返回值,終止當前線程

核心功能:

  • 終止線程執行:調用 pthread_exit() 的線程會立即停止執行,并釋放其占用的資源(如棧空間),但不會釋放整個進程的資源。
  • 傳遞返回值:retval 作為返回值被傳遞給等待該線程的其他線程。
  • 不影響其他線程:僅終止當前線程,不會影響進程中的其他線程或主線程。

參數說明:

  • void* retval:線程的返回值,可通過 pthread_join() 的 retval 參數獲取。 若無需返回值,可傳 NULL。

3.2 pthread_self()

pthread_self()函數用于線程獲取自身的線程ID。

#include <pthread.h>pthread_t pthread_self(void);  // 返回當前線程的 ID

返回調用該函數的線程的唯一標識符。

3.3?pthread_cancel()

pthread_cancel() 是 POSIX 線程庫中用于請求終止某一個線程的函數。

#include <pthread.h>int pthread_cancel(pthread_t thread);  // 請求取消指定線程

?核心功能:

  • 發送取消請求:pthread_cancel() 向目標線程發送一個 “取消請求”,而非強制終止。線程是否響應以及如何響應取決于其取消狀態和取消類型。
  • 取消點:預定義的系統調用(如 sleep()、read()、write()、pthread_join() 等),線程在執行這些函數時會檢查并處理取消請求。

參數說明:

  • pthread_t thread:要取消的線程 ID(由 pthread_create() 返回)。?

返回值:

  • 成功:返回 0。
  • 失敗:返回錯誤碼(如 ESRCH,表示線程 ID 不存在)。?

?示例代碼:

// 終止自己==pthread_exit()
pthread_cancel(pthread_self());

4. 線程分離:pthread_detach()

pthread_detach() 是 POSIX 線程庫中用于將線程設置為分離狀態的函數。

分離狀態的線程在終止后,會自動釋放其占用的系統資源(如線程描述符、棧空間),無需其他線程調用 pthread_join() 回收。

并且其他線程調用pthread_join()對分離狀態的線程進行回收是非法的,會導致未定義錯誤。

#include <pthread.h> int pthread_detach(pthread_t thread); // 設置線程為分離狀態

參數說明:

  • pthread_t thread:要設置為分離狀態的線程 ID(由 pthread_create() 返回)。

返回值:

  • 成功:返回 0。
  • 失敗:返回錯誤碼(如 ESRCH、EINVAL 等)。?

注意事項:

  • 分離狀態不可逆轉:一旦線程被設置為分離狀態,無法再變回 joinable 狀態。
  • 返回值無法獲取:分離線程的返回值會被自動丟棄,不能通過 pthread_join() 獲取。
  • 資源釋放的確定性:分離線程終止后,系統會立即回收其資源,無需等待其他線程操作。
  • 錯誤處理:若對已終止的線程調用 pthread_detach(),可能返回 ESRCH。 若對已分離的線程重復調用 pthread_detach(),可能返回 EINVAL。?

示例代碼:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>void* detached_thread(void* arg) {printf("分離線程開始運行...\n");sleep(2);  // 模擬耗時操作printf("分離線程結束\n");return NULL;
}int main() {pthread_t thread_id;// 創建新線程if (pthread_create(&thread_id, NULL, detached_thread, NULL) != 0) {perror("線程創建失敗");return 1;}// 將線程設置為分離狀態if (pthread_detach(thread_id) != 0) {perror("設置分離狀態失敗");return 1;}printf("主線程繼續執行,不等待分離線程\n");// 主線程可以提前退出,分離線程仍會繼續執行sleep(1);printf("主線程退出\n");return 0;
}
// 分離自己
pthread_detach(pthread_self());

5. 線程標識符

在 Linux 系統中,pthread_t 類型的線程標識符(tid)本質上是一個輕量級進程(LWP)ID或指向線程控制塊的指針。

5.1 線程控制塊(TCB)

每個線程在內核中對應一個 task_struct 結構(與進程相同),但共享父進程的資源。

而在用戶空間中,經過pthread庫的包裝之后另外設置了一種數據結構來維護額外的線程數據,即TCB,包括如下控制信息:

  • 線程狀態(運行、阻塞等)
  • 線程棧地址和大小
  • 信號掩碼
  • 內核 LWP ID

?5.2 pthread_t類型的本質

在 Linux 中,pthread_t 的具體類型定義取決于實現:

  • glibc/NPTL:pthread_t 通常是一個 struct pthread*,即指向線程控制塊的指針
  • 用戶可見性:pthread_t 對用戶是不透明的,只能通過 POSIX 線程 API 操作。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/84898.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/84898.shtml
英文地址,請注明出處:http://en.pswp.cn/web/84898.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Ragflow 源碼:ragflow_server.py

目錄 介紹1. 初始化和配置2. 數據庫管理3. 核心功能4. HTTP 服務5. 信號處理6. 調試支持 流程圖系統架構 代碼解釋1. **初始化系統**2. **運行時控制**3. **核心服務** 介紹 ragflow_server.py 是 RAGFlow 項目的主服務器程序&#xff0c;負責啟動和管理 RAGFlow 的核心服務。…

springboot企業級項目開發之項目測試——單元測試!

項目測試 項目測試是對項目的需求和功能進行測試&#xff0c;由測試人員寫出完整的測試用例&#xff0c;再按照測試用例執行測試。項目測試是項目質量的保證&#xff0c;項目測試質量直接決定了當前項目的交付質量。 測試人員在開展測試之前&#xff0c;首先需要進行測試的需…

Linux kdump遠程轉存儲配置手冊教程

一、前言 kdump是一個Linux內核崩潰轉儲機制,當系統崩潰時,它可以捕獲內核的內存轉儲信息,幫助分析崩潰原因。將轉儲文件存儲到遠程位置,便于集中管理和分析。本教程將詳細介紹如何配置kdump將轉儲文件遠程轉存儲。 二、安裝kdump 在大多數Linux發行版中,kdump相關的工…

c++bind和forward完美轉化

前言 1. std::bind概述 std::bind是C11引入的功能模板&#xff0c;位于<functional>頭文件中&#xff0c;用于將函數、成員函數或函數對象與特定參數綁定&#xff0c;生成一個新的可調用對象。 1.1 基本用法 #include <iostream> #include <functional>v…

【Dify精講】第14章:部署架構與DevOps實踐【知識卡片】

第14章&#xff1a;部署架構與DevOps實踐http://www.airinto.com/share/49997bb7 一、Docker 容器化方案&#xff1a;從開發到生產的統一 二、Kubernetes 部署&#xff1a;走向云原生 三、CI/CD 流程設計&#xff1a;自動化的藝術 四、高可用架構&#xff1a;讓 AI 服務永不停歇…

el-cascader 設置可以手動輸入也可以下拉選擇

el-cascader 設置可以手動輸入也可以下拉選擇 稍微修改一下就可食用 <template slot"stationId" slot-scope""><div style"position: relative;"><!-- 可輸入也可顯示選項 --><el-input:value"stationNameInput"…

Unity Shader開發-著色器變體(1)-著色器變體概述

有時我們希望一份 Shader 源代碼可能滿足多種功能&#xff08;如處理法線貼圖、自發光、不同光照模式、陰影&#xff0c;支持GPUInstacing等多種功能&#xff09;。所以我們需要能夠實現Shader分支的方法。 一.Shader分支實現 主要有三種手段實現Shader分支&#xff1a; 1.靜…

ECK 簡化:在 GCP GKE Autopilot 上部署 Elasticsearch

作者&#xff1a;來自 Elastic Eduard Martin 學習如何使用 GKE Autopilot 和 ECK 在 GCP 上部署 Elasticsearch 集群。 想要獲得 Elastic 認證&#xff1f;了解下一次 Elasticsearch Engineer 培訓的時間&#xff01; Elasticsearch 擁有豐富的新功能&#xff0c;可以幫助你為…

測試一個軟件的性能有哪些指標?

在測試軟件性能時,通常會關注多個維度的指標,以評估系統在不同負載下的表現。以下是關鍵的性能測試指標分類和詳細說明: ?? 核心性能指標分類 1. 響應時間(Response Time) 定義:從發送請求到接收到響應所花費的時間 細分: 平均響應時間:所有請求的平均耗時 *P90/P95…

淺析std::atomic<T>::compare_exchange_weak和std::atomic<T>::compare_exchange_strong

目錄 std::atomic ::compare_exchange_weak 和 std::atomic ::compare_exchange_strong 核心原理 函數簽名 核心區別 典型用法 1. compare_exchange_weak&#xff08;循環內重試&#xff09; 2. compare_exchange_strong&#xff08;單次嘗試&#xff09; 底層機制 總…

舉出一個異步接口測試的例子

以下是一個完整的 ?異步接口測試? 實際案例&#xff0c;包含問題場景、解決方案、代碼實現和面試回答技巧&#xff0c;適合在面試中展示技術深度&#xff1a; ?案例背景? ?業務場景?&#xff1a; 測試一個AI圖片生成平臺的異步接口&#xff0c;用戶提交生成請求后&#…

更新麒麟連不上外網

問題&#xff1a;更新麒麟連不上外網 處理&#xff1a;本地建個下載地址 建立文件夾/root/x86.rpm&#xff0c;子文件夾&#xff1a;Packages、repodata&#xff0c;和在線站點建的一樣&#xff1a;Index of /NS/V10/V10SP1.1/os/adv/lic/base/x86_64/&#xff0c;然后就下載…

TensorFlow深度學習實戰——使用Hugging Face構建Transformer模型

TensorFlow深度學習實戰——使用Hugging Face構建Transformer模型 0. 前言1. 安裝 Hugging Face2. 文本生成3. 自動模型選擇和自動分詞4. 命名實體識別5. 摘要生成6. 模型微調相關鏈接 0. 前言 除了需要實現特定的自定義結構&#xff0c;或者想要了解 Transformer 工作原理外&…

SAP-ABAP:SAP全模塊的架構化解析,涵蓋核心功能、行業方案及技術平臺

一、核心業務模塊&#xff08;Logistics & Operations&#xff09; 模塊代號核心功能典型流程關鍵事務碼物料管理MM采購/庫存/發票校驗采購到付款 (P2P)ME21N&#xff08;采購訂單&#xff09;, MI31&#xff08;庫存盤點&#xff09;銷售與分銷SD訂單/定價/發貨/開票訂單…

實時預警!機場機坪井室無線智能液位監測系統助力安全降本

某沿海機場因地處多雨區域&#xff0c;每年雨季均面臨排水系統超負荷運行壓力。經勘測發現&#xff0c;5個井室因長期遭受地下水滲透侵蝕&#xff0c;井壁出現細微結構性裂縫&#xff0c;導致內部水位異常升高。作為機坪地下管網系統的核心節點&#xff0c;這些井室承擔著雨水導…

邊云協同 AI 視頻分析系統設計方案

目錄 一、項目背景與目標 二、系統架構概述 總體架構圖 三、ER 圖&#xff08;核心數據庫設計&#xff09; 實體關系圖簡述 數據表設計&#xff08;簡要&#xff09; 四、模型結構圖&#xff08;邊緣云端AI推理架構&#xff09; 邊緣模型&#xff08;YOLOv5-tiny/PP-YO…

vue3整合element-plus

為項目命名 選擇vue 框架 選擇TS 啟動測試&#xff1a; npm run dev 開始整合 element-plus npm install element-plus --save npm install unplugin-vue-components unplugin vitejs/plugin-vue --save-dev 修改main.ts import { createApp } from vue import ./style.cs…

【AI 測試】測試用例設計:人工智能語言大模型性能測試用例設計

目錄 一、性能測試可視化架構圖 &#xff08;1&#xff09;測試整體架構圖 &#xff08;2&#xff09;測試體系架構圖 &#xff08;3&#xff09;測試流程時序圖 二、性能測試架構總覽 &#xff08;1&#xff09;性能測試功能點 &#xff08;2&#xff09;測試環境要…

Windsurf SWE-1模型評析:軟件工程的AI革命

引言 軟件開發領域正經歷著前所未有的變革&#xff0c;AI輔助編程工具層出不窮&#xff0c;但大多數僅專注于代碼生成這一環節。Windsurf公司近期推出的SWE-1系列模型打破了這一局限&#xff0c;首次將AI應用擴展至軟件工程的全流程。這一舉措不僅反映了行業對AI工具認知的深化…

Qt for OpenHarmony 編譯鴻蒙調用的動態庫

簡介 Qt for Harmony? 是跨平臺開發框架 ?Qt? 與華為 ?OpenHarmony? 操作系統的深度集成方案&#xff0c;由 Qt Group 與華為聯合推動。其核心目標是為開發者提供一套高效工具鏈&#xff0c;實現 ??“一次開發&#xff0c;多端部署”?&#xff0c;加速 OpenHarmony 生…