【Linux多線程】認識多線程創建線程

文章目錄

  • 什么是多線程
    • 為什么稱linux下的線程是輕量級進程呢?
  • 線程的優點
  • 線程的缺點
  • 線程異常
  • 線程和進程
  • 創建線程
    • 1.pthread_create
    • 2.pthread_self

什么是多線程

進程是正在運行的程序的實例,而線程(thread)是進程中的一個執行路線。一個進程可以擁有多個線程。從程序的角度上來說,線程是一個獨立運行程序的片段。當程序運行時,進程把大部分資源合理分配給每個執行流(線程),且所有線程共享進程的地址空間,所以線程實際上就是一個輕量級的進程。下面給出進程中的線程示意圖:


值得注意的是,windos下的線程是有線程控制塊(TCB)的。而linux下的進程控制塊和線程控制塊都是task_struct

為什么稱linux下的線程是輕量級進程呢?

這是因為linux內核并沒有單獨為線程設計一套管理方案,而是通過相同的機制來管理進程和線程,只不過線程擁有的資源是進程的一部分,所以稱linux下的線程是輕量級進程。并且,Linux內核中的調度器并不區分線程和進程,可以是單線程的進程,也可以只是一個線程。為了讓用戶使用起來區分線程和進程,linux向上(用戶態)提供了POSI標準的線程接口(如pthread庫),在內核用clone系統調用創建和管理線程。盡管有線程這個模型,但底層還是輕量級的進程

總結:==線程是共享同一進程的地址空間和資源的執行單元=。

線程的優點

  1. 共享資源:同一進程內的線程共享地址空間,能訪問相同的全局變量,堆和文件描述符等。這種共享使得線程間通信變得更加高效。
  2. 獨立的執行流:每個線程都有自己的程序計數器、寄存器和棧,這使得線程可以獨立執行。線程的獨立性使得多個線程并行執行多個任務,提高了此程序的響應性和吞吐量。
  3. 輕量級:相比于進程,線程的創建開銷會小很多,且不需要分配獨立的地址空間。上下文切換也比進程快,因為不涉及地址空間的切換
    4.并發執行:在多核處理器上,不同的線程可以做到真正的并行執行

線程的缺點

  1. 同步復雜性:由于共享進程空間,多個線程同時訪問和修改共享數據時可能會導致數據不一致等問題
  2. 性能損失:使用鎖和其它同步機制會導致性能下降
  3. 調試難度提高:編寫和調試一個多線程程序要比單線程程序困難得多

線程異常

  • 單個線程如果出現除0或者訪問野指針等問題導致線程崩潰,進程也會隨著崩潰
  • 進程終止,該進程的所有線程都會終止。這也就意味著,如果某一個線程出了異常進而終止進程的話,其它的線程也都會被終止。這也是線程不安全的原因之一。

線程和進程

  • 進程是資源分配的基本單位,而線程是調度的基本單位
  • 具體來說,線程共享以下進程資源:
    • 代碼段和數據段
    • 文件描述符表
    • 每種信號的處理方式即handler表
    • 環境變量包括當前工作目錄
    • 用戶id和組id
  • 雖然線程共享進程的數據,但有屬于自己的一些數據:
    • 線程ID
    • 一組寄存器
    • errno錯誤流
    • 信號屏蔽字
    • 調度優先級

進程和線程的關系如下圖:
在這里插入圖片描述

創建線程

在linux中,通常使用POSIX線程庫,即pthread庫。pthread庫提供了一組用于線程創建、管理和同步的函數,這些函數被包含在pthread.h頭文件中。pthread庫的主要包含了線程管理、線程同步、線程屬性相關的函數,下面介紹線程管理中的一些常用函數。

1.pthread_create

功能:創建一個新的線程
原型:

#include<pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *
(*start_routine)(void*), void *arg);
  • pthread_t是一個無符號整數
  • thread是指向pthread_t變量的一個指針,用于存儲創建線程的標識符ID(輸出型參數)
  • pthread_attr_t類型是一個線程屬性的類,該類定義了線程的所有屬性,包括分離狀態、棧的大小等
  • attr是一個指向const pthread_attr_t對象的指針,用于初始化被創建線程的屬性。如果設置為NULL,則使用默認屬性
  • start_rountine是一個函數指針,該函數的參數和返回值類型都是void*。表示線程線程執行的函數
  • arg是傳遞給線程函數的參數。可以是NULL,如果需要傳遞多個參數,可以將其打包成結構體類型對象傳進去。同樣如果想返回多個值,可以將值打包成一個結構體再返回。
  • 創建成功返回0。失敗則返回一個非0值,表示錯誤代碼。常見得到錯誤碼有:
    • EAGAIN:系統資源不足,無法創建更多線程。
    • EINVAL:無效的線程屬性
    • EPERM:沒有足夠的權限設置線程屬性

給出代碼樣例,演示使用pthread_create創建線程:

#include <pthread.h>
#include <iostream>
#include <unistd.h>
#include <string.h>using namespace std;void *rout(void *arg)//線程執行函數
{while (true){cout << "i am thread num: " << *(int *)arg << endl;sleep(1);}return NULL;
}int main()
{pthread_t tid;int num = 10;int res = pthread_create(&tid, NULL, rout, (void *)(&num));if (res != 0){//錯誤碼檢查fprintf(stderr, "pthread_create: %s\n", strerror(res));exit(1);}while (true){cout << "I am main thread" << endl;sleep(1);}return 0;
}

在這里插入圖片描述
這樣我們就成功的使用pthread_create函數創建了一個線程。值得注意的是,執行main函數的線程我們稱為主線程。此外,一個線程可以使用pthread_self函數來獲取自己的線程ID.

2.pthread_self

功能:獲得當前線程的ID
函數原型:

pthread_t pthread_self(void);

于是我們可以將前面的代碼樣例改一下,觀察結果線程ID:

#include <pthread.h>
#include <iostream>
#include <unistd.h>
#include <string.h>using namespace std;void *rout(void *arg)
{while (true){cout << "thread id : " << pthread_self() << " i am thread num: " << *(int *)arg << endl;sleep(1);}return NULL;
}int main()
{pthread_t tid;int num = 10;int res = pthread_create(&tid, NULL, rout, (void *)(&num));if (res != 0){fprintf(stderr, "pthread_create: %s\n", strerror(res));exit(1);}while (true){cout << "tid: " << tid << "  I am main thread" << endl;sleep(1);}return 0;
}

在這里插入圖片描述
我i們可以觀察到,線程ID是一個非常復雜的數字,這個具體數值通常是由線程庫內部實現的,可能會使用內存地址等機制來生成唯一的線程ID。

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

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

相關文章

python 刪除pdf 空白頁

環境 python 3.10 PyPDF2 3.0.1 安裝 pip install PyPDF2流程 將空白頁和內容頁讀取出來&#xff0c;看看內部結構有什么不同以此為依據&#xff0c;遍歷整個PDF 文件&#xff0c;標記處有內容的頁面&#xff0c;寫入到另外一個PDF文件。 python 代碼 # 每一個頁都是一個…

Springboot郵件發送配置

Springboot郵件發送配置 pom.xml依賴&#xff1a; <dependency><groupId>org.eclipse.angus</groupId><artifactId>jakarta.mail</artifactId><version>2.0.3</version> </dependency> <dependency><groupId>or…

跨域的解決方案

1. 計算機更改跨域 1.C盤->Windows->System32->drivers->etc 2.修改hosts 文件2. Chrome瀏覽器的跨域設置 操作步驟&#xff1a;1.打開我的電腦——C盤 新建一個文件夾&#xff0c;命名為MyChromeDevUserData2.右鍵——Chrome——快捷方式——目標&#xff0c;在…

ChatGPT成知名度最高生成式AI產品,使用頻率卻不高

5月29日&#xff0c;牛津大學、路透社新聞研究所聯合發布了一份生成式AI&#xff08;AIGC&#xff09;調查報告。 在今年3月28日—4月30日對美國、英國、法國、日本、丹麥和阿根廷的大約12,217人進行了調查&#xff0c;深度調研他們對生成式AI產品的應用情況。 結果顯示&…

ElementUI之el-table標題列中顯示el-tooltip

ElementUI之el-table標題列中顯示el-tooltip 文章目錄 ElementUI之el-table標題列中顯示el-tooltip1. el-table標題列中顯示el-tooltip2. 實現代碼3. 展示效果 1. el-table標題列中顯示el-tooltip 在el-table-column標簽內添加具名插槽v-slot:header 在el-tooltip標簽中使用具…

【幾何】輸入0-360度任意的角度,求上面直線與橢圓相切點的坐標計算公式

?輸入0-360度任意的角度,求上面直線與橢圓相切點的坐標計算公式 使用積分計算 使用到的公式有橢圓公式: x 2 a 2 + y 2 b 2 = 1 \frac{x^2}{a^2}+\frac{y^2}{b^2} = 1 a2x2?+b2y2?=1 平面旋轉公式 X r = cos ? θ ? ( X s ? X O ) ? sin ? θ ? ( Y s ? Y O ) + X …

端午節粽子龍舟主題互動趣味小游戲效果是什么

端午三天樂&#xff0c;無論節日當天還是之前&#xff0c;行業商家都可以自己的品牌為主借勢營銷&#xff0c;趣味活動形式玩法和內容呈現達成多種效果&#xff0c;品牌傳播、公眾號漲粉、線下互動、商品促銷、用戶促活等。 在【雨科】平臺擁有多款端午節互動小游戲類型&#…

網易狼人殺 設置點擊自動發言

我們玩網易狼人殺 剛開始 都會發現 要按住麥克風才能發言 不得不說 相當的麻煩 我們可以點擊如下圖 右上角這個設置的齒輪 新彈出的設置面板上 勾選這個點擊發言 然后 我們只需要 點一下 就可以進入發言狀態 然后 再點一下即可停止發言 會方便非常多

zabbix事件告警監控:如何實現對相同部件觸發器告警及恢復的強關聯

有一定Zabbix使用經驗的小伙伴可能會發現&#xff0c;接收告警事件時&#xff0c;其中可能包含著大量不同的部件名&#xff0c;同一部件的事件在邏輯上具有很強關聯性&#xff0c;理論上應保持一致的告警/恢復狀態&#xff0c;但Zabbix默認并未對它們進行關聯&#xff0c;直接后…

AIGC降重:如何2分鐘降低論文AI率和查重率?推薦使用SpeedAI科研小助手

確保學術論文的獨立性與誠信性&#xff0c;對于學業的成就及學位的獲取至關重要&#xff0c;其中&#xff0c;論文的人工智能查重與降低AIGC相似度扮演著核心角色。 常規的查重手段主要圍繞查重軟件的運用和個體的自行審查&#xff1b;而降重則通常通過語句重組、同義替換、內…

單細胞分析(Signac): PBMC scATAC-seq 基因組區域可視化

引言 在本教學指南中&#xff0c;我們將探討由10x Genomics公司提供的人類外周血單核細胞&#xff08;PBMCs&#xff09;的單細胞ATAC-seq數據集。 加載包 首先加載 Signac、Seurat 和我們將用于分析人類數據的其他一些包。 if (!requireNamespace("EnsDb.Hsapiens.v75&qu…

ModuleNotFoundError: No module named ‘osgeo‘

顯示無osgeo模塊 pip install osgeo顯示失敗 方法&#xff1a; 確保你已經安裝了正確的依賴項&#xff0c;例如GDAL、GEOS和PROJ等。 方法1&#xff1a;pip install gdal 失敗 方法2&#xff1a;官網下載失敗&#xff0c;下載地址&#xff1a;https://www.lfd.uci.edu/~gohl…

在Linux系統中,使用OpenSSL生成私有證書文件,并提取私鑰的步驟如下:

在Linux系統中&#xff0c;使用OpenSSL生成私有證書文件&#xff0c;并提取私鑰的步驟如下&#xff1a; 生成私鑰&#xff08;如果還沒有私鑰的話&#xff09;&#xff1a; openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:2048 生成自簽名證書&…

設置自動刷新數據透視表的數據源

數據透視表數據源的自動刷新 一般情況操作&#xff1a; 自動刷新操作&#xff1a; 1、定義名稱名稱 引用位置&#xff1a;OFFSET(Sheet1!$A$1,0,0,COUNTA(Sheet1!$A:$A),COUNTA(Sheet1!$1:$1)) 2、數據透視表的數據源更改為【源數據】—— 即前面定義的名稱 3、數據——全部…

Java多線程——觀測線程狀態

線程可以處于以下幾個狀態&#xff1a; NEW&#xff1a;尚未啟動的線程處于此狀態&#xff1b; RUNNABLE&#xff1a;在Java虛擬機中執行的線程處于此狀態&#xff1b; BLOCKED&#xff1a;被阻塞等待監視器鎖定的線程處于此狀態&#xff1b; WAITING&#xff1a;正在等待…

區塊鏈技術和應用二

前言 學習長安鏈的一些基本原理 官網&#xff1a;長安鏈開源文檔 b站課程&#xff1a;區塊鏈基礎與應用 一、共識算法 1.1 POW工作量證明 最長鏈共識&#xff0c;沒聽明白 1.2 51%攻擊 二、區塊鏈的發展 2.1 區塊鏈1.0到3.0 2.2 共有鏈、聯盟鏈、私有鏈 2.3 發展趨勢 2.4 擴…

CUDA_VISIBLE_DEVICES‘ 不是內部或外部命令,也不是可運行的程序或批處理文件。

問題&#xff1a; 命令行出現CUDA_VISIBLE_DEVICES0 python trainer.py這種命令 這是Linux可以的&#xff0c;但是Windows不行。 解決方案&#xff1a; 這條命令的含義是指定某個GPU來運行程序&#xff0c;我們可以在程序開頭添加指定GPU的代碼&#xff0c;效果是一樣的&…

HackTheBox-Machines--Lazy

Lazy測試過程 1 信息收集 1.端口掃描 發現 SSH&#xff08;22&#xff09;、HTTP&#xff08;80&#xff09;端口 nmap -sC -sV 10.129.159.512.訪問 80 端口 1.頁面中存在注冊功能&#xff0c;測試注冊功能 頁面返回登錄頁面及用戶名 使用burpsuite觀察注冊請求 /register.p…

Facebook:連接世界,暢游社交之旅

作為全球最大的社交平臺之一&#xff0c;Facebook不僅僅是一個網站&#xff0c;更是一個連接世界的橋梁&#xff0c;讓人們可以輕松地與全球各地的朋友、家人和同事保持聯系&#xff0c;分享生活、交流想法&#xff0c;暢游社交的無邊界之旅。本文將帶領讀者探索Facebook的魅力…

電子商務網站(網上商店PetShop)

PetShop是一個范例&#xff0c;微軟用它來展示.Net企業系統開發的能力。PetShop隨著版本的不斷更新&#xff0c;至現在基于.Net2.0的PetShop 4.0為止&#xff0c;整個設計逐漸變得成熟而優雅&#xff0c;有很多可以借鑒之處。PetShop是一個小型的項目&#xff0c;系統架構與代碼…