理解計算機系統_并發編程(5)_基于線程的并發(二):線程api和基于線程的并發服務器

前言
? ? ? ?

? ? ? ? 以<深入理解計算機系統>(以下稱“本書”)內容為基礎,對程序的整個過程進行梳理。本書內容對整個計算機系統做了系統性導引,每部分內容都是單獨的一門課.學習深度根據自己需要來定

引入

? ? ? ? 接續上一篇理解計算機系統_并發編程(4)_基于線程的并發(一):線程基礎-CSDN博客

Posix線程簡介

? ? ? ? 概念:Posix線程是在C程序中處理線程的一個標準接口.而且在所有Linux系統上都可用.Pthreads定義了大約60個函數,允許程序創建,殺死和回收線程,與對等線程安全地共享數據,還可以通知對等線程系統狀態地變化.

? ? ? ? ---解讀:有api可以用是讓人興奮的,代碼要寫起來.

一個簡單的Pthreads程序

? ? ? ? 主函數(代表主線程)創建一個對等線程,然后等待他的終止.當主線程檢測到對等線程終止后,他就通過調用exit終止該進程.

hello.c內容

#include"csapp.h"
void *thread(void *vargp);int main(){pthread_t tid;Pthread_create(&tid,NULL,thread,NULL); //生成對等線程Pthread_join(tid,NULL);                //等待對等線程終止exit(0);                               //終止當前進程中所有線程
}void *thread(void *vargp){printf("Hello,world!\n");return NULL;
}

? ? ? ? ---解讀:從示例代碼可以看出:線程和任務是分離的.主程序只管線程的生成和終止.任務由函數thread給出.二者之間的聯系在Pthread_create()函數里,兩個參數分別傳入了函數名thread和代表參數vargp的NULL.---"分離"是構建程序時常用的方法.他的優點是便于模塊化代碼,也便于分工.

任務函數的分析

? ? ? ? 本書原話:線程的代碼和本地數據被封裝在一個線程例程(thread routine)中.正如第二行里的原型所示,每個線程例程都以一個通用指針作為輸入,并返回一個通用指針.如果想傳遞多個參數給線程例程,那么你應該將參數放到一個結構中,并傳遞一個指向該結構的指針.相似地,如果想要線程例程返回多個參數,你可以返回一個指向一個結構的指針. ---斜體字部分有解釋

? ? ? ? ---解讀:通用指針可以表示的數據,理論上是無限的.他可以指向一個結構(或結構數組),結構里面再擴展數據.

? ? ? ? 這里有一個疑問:"線程例程返回多個參數,可以返回一個指向一個結構的指針",問題是線程例程的返回值在哪里?主函數中并沒有接收.

????????解決方案:輸入參數和返回值放進一個結構(vargp)里.? 舉個例子,聲明一個結構表示結果和參數

typedef struct{struct result* res;struct argument* arg;
}res_arg;

? ? ? ? 給Pthread_create傳第4個參數時傳入struct res_arg*類型的數據.形參和返回值的數據分別由struct result和struct argument定義.

? ? ? ? 這種寫法的思路是用形參指針接收函數返回值.筆者以前寫過:理解計算機系統_網絡編程(4)_套接字api-CSDN博客

線程API? ? ? ??

創建線程pthread_create()?

? ? ? ? 函數原型如下

typedef void *(func)(void *);int pthread_create(pthread_t *tid,pthread_attr_t *attr,func *f, void *arg);    //成功返回值為0,出錯為非0

? ? ? ? ?---解讀:函數等于任務,用函數指針func表示,然后把函數指針和參數指針傳入pthread_create()函數的第3個和第4個形參中,表示函數被放入線程tid中運行.

? ? ? ? 第1個參數tid理解為生成一個線程ID.結合主函數來看:定義一個pthread_t變量,傳入地址給函數.當pthread_create()返回時,參數tid包含新創建線程的ID.---黑體字是原話,佐證

? ? ? ? 第2個參數attr改變新創建線程的默認屬性.本書認為改變這些屬性超出學習范圍,調用時總傳入NULL

獲得自己的線程ID函數pthread_self()

? ? ? ? 函數原型

pthread_t pthread_self(void);
//返回調用者的線程ID

? ? ? ? 顯然獲得自己的線程必須在生成線程號之后---必須先調用pthread_create()

終止線程

? ? ? ? 一個線程的終止的方式:

? ? ? ? 1.當頂層的線程例程返回時,線程會隱式地終止. ---任務執行后所在線程自動終止,不需要干預

? ? ? ? 2.通過調用pthread_exit函數,線程會顯式地終止.函數原型如下:

void pthread_exit(void *thread_return);
//不返回

? ? ? ? 3.某個對等線程調用Linux的exit函數,該函數終止進程以及所有與該進程相關的線程.

? ? ? ? 4.另一個對等線程通過以當前ID作為參數調用pthread_cancel函數來終止當前進程.

? ? ? ? ---解讀:筆者認為以上方法沒有多少應用場景,

????????比如第4條,讓一個線程終止另一個線程,意義何在?第3條調用exit函數,相當于強制退出所有線程和進程.第2條由主線程調用后等待并終止,和示例程序中主線程調用exit的意思是相同的,多了一個thread_return可以設置一些數據,而這個工作可以留到"回收已終止線程的資源"里去做.

? ? ? ? 綜上所述,暫時不用多看,用示例里的寫法即可.如果有遇到相應場景再來查.

回收已終止線程的資源pthread_join()函數

? ? ? ? 函數原型

int pthread_join(pthread_t tid,void **thread_return);
//成功返回0,出錯則為非0

? ? ? ? ---解讀:函數會阻塞,直到線程終止,回收已終止線程的資源.有兩點說明

? ? ? ? 1>必須指定線程ID,這點和進程中的wait函數不一樣,先執行完的子進程調用wait? ?

? ? ? ? ?2>將線程例程返回的通用(void *)指針賦值為thread_return指向的位置.這里解決了上面標題"任務函數的分析"提出的疑問:線程任務運行的返回值去了哪里?線程返回的結構指針,被另一個雙重指針接收.

分離線程pthread_detach()函數

? ? ? ? 線程分離detach和線程結合join是相對的.

? ? ? ? ?本書原話:一個可結合的線程能夠被其他線程收回和殺死.在被其他線程回收之前,他的內存資源(例如棧)是不釋放的.相反,一個分離的線程是不能被其他線程回收或殺死,他的內存資源在他終止時由系統自動釋放.

? ? ? ? 函數原型

int pthread_detach(pthread_t tid);
//若成功返回0,出錯返回非0

? ? ? ? ?同時,線程能夠以pthread_self()為參數調用來分離自己.

? ? ? ? ---解讀:線程資源面臨釋放問題,join和detach二選一.兩者對比如下:

????????join顯式釋放資源,并接收線程任務返回值(也是顯式).

????????detach自動釋放資源,暫時沒看見接收線程任務返回值的地方(如果需要接收,可以把輸入參數和返回值放進一個結構(vargp)里),寫法上detach相對簡單一點(見本書P695"基于線程的并發服務器"代碼)

初始化線程pthread_once()函數(略)

基于線程的并發echo服務器? ?

? ? ? ?本書P695中間echoservert.c,這里代碼在之前基礎上稍作了修改.還是不難看懂,

? ? ? ? 注意:

? ? ? ? 1>第21行代碼可以和第8行合并,寫到第8行

int *connfdp=Malloc(sizeof(int));

? ? ? ? 2>第22行,第23行和第30行結合看,把已連接描述符connfd(int類型)先作為指針傳入pthread_create,然后在thread函數中,先強轉為int型指針,再提取出描述符的寫法.

? ? ? ? 3>第31行線程資源回收調用了detach()函數,在任務中先分離自己,自動回收資源

? ? ? ? 4>后面講了出錯的原因是"競爭"

小結

? ? ? ? 線程api的一點理解

????????

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

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

相關文章

使用PhpStudy搭建Web測試服務器

一、安裝PhpStudy 從以下目錄下載PhpStudy安裝文件 Windows版phpstudy下載 - 小皮面板(phpstudy) (xp.cn) 安裝成功之后打開如下界面 點擊啟動Apache 查看網站地址 在瀏覽器中輸入localhost:88,出現如下頁面就ok了 二、與Unity交互 1.配置下載文件路徑&#xff0c;點擊…

cocos creator 3.8 下的 2D 改動

在B站找到的系統性cocos視頻教程,純2D開發入門,鏈接如下: zzehz黑馬程序員6天實戰游戲開發微信小程序&#xff08;Cocos2d的升級版 CocosCreator JavaScript&#xff09;_嗶哩嗶哩_bilibili黑馬程序員6天實戰游戲開發微信小程序&#xff08;Cocos2d的升級版 CocosCreator Ja…

【Hot 100】208. 實現 Trie (前綴樹)

目錄 引言實現 Trie (前綴樹)我的解題代碼解析代碼思路分析優化建議1. 內存泄漏問題2. 使用智能指針優化內存管理3. 輸入合法性校驗&#xff08;可選&#xff09;4. 其他優化 總結 &#x1f64b;?♂? 作者&#xff1a;海碼007&#x1f4dc; 專欄&#xff1a;算法專欄&#x1…

Unity3D仿星露谷物語開發42之粒子系統

1、目標 使用例子系統&#xff0c;實現割草后草掉落的特效。 通過PoolManager獲取特效預制體&#xff0c;通過VFXManager來觸發特效。 2、配置例子特效 在Hierarchy -> PersistentScene下創建新物體命名為Reaping。 給該物體添加Particle System組件。 配置例子系統參數…

視覺-語言基礎模型作為高效的機器人模仿學習范式

摘要 近期&#xff0c;視覺語言基礎模型領域取得的進展彰顯了其在理解多模態數據以及解決復雜視覺語言任務&#xff08;包括機器人操作任務&#xff09;方面的能力。我們致力于探尋一種簡便的方法&#xff0c;利用現有的視覺語言模型&#xff08;VLMs&#xff09;&#xff0c;僅…

zst-2001 上午題-歷年真題 算法(5個內容)

回溯 算法 - 第1題 找合適的位置&#xff0c;如果沒有位置就按B回家 d 分治 算法 - 第2題 b 算法 - 第3題 a 算法 - 第4題 劃分一般就是分治 a 算法 - 第5題 分治 a 0-1背包 算法 - 第6題 c 算法 - 第7題 最小的為c 3100 c 算法 - 第8題 …

淺論3DGS濺射模型在VR眼鏡上的應用

擺爛仙君小課堂開課了&#xff0c;本期將介紹如何手搓VR眼鏡&#xff0c;并將隨手拍的電影變成3D視頻。 一、3DGS模型介紹 3D 高斯模型是基于高斯函數構建的用于描述三維空間中數據分布概率的模型&#xff0c;高斯函數在數學和物理領域有著廣泛應用&#xff0c;其在 3D 情境下…

2025年中期大語言模型實力深度剖析

I. 引言&#xff1a;解讀2025年動態LLM競技場中的“實力” 用戶提出的“如今哪個大語言模型最強”這一問題&#xff0c;精準地反映了業界對飛速發展的人工智能&#xff08;AI&#xff09;領域的高度關注。本報告基于截至2025年5月的最新數據&#xff0c;旨在對這一問題進行全面…

Spark緩存-cache

一、RDD持久化 1.什么時候該使用持久化&#xff08;緩存&#xff09; 2. RDD cache & persist 緩存 3. RDD CheckPoint 檢查點 4. cache & persist & checkpoint 的特點和區別 特點 區別 二、cache & persist 的持久化級別及策略選擇 Spark的幾種持久化…

嵌入式開發學習日志(數據結構--順序結構單鏈表)Day19

一、順序結構 安裝軟件命令&#xff1a; sudo apt-get install (軟件名) 安裝格式化對齊&#xff1a;sudo apt-get install clang-format 內存泄漏檢測工具&#xff1a; sudo apt-get install valgrind 編譯后&#xff0c;使用命令 valgrind ./a.out 即可看內…

第六節第二部分:抽象類的應用-模板方法設計模式

模板方法設計模式的寫法 建議使用final關鍵字修飾模板方法 總結 代碼&#xff1a; People(父類抽象類) package com.Abstract3; public abstract class People {/*設計模板方法設計模式* 1.定義一個模板方法出來*/public final void write(){System.out.println("\t\t\t…

2025年滲透測試面試題總結-滲透測試紅隊面試三(題目+回答)

網絡安全領域各種資源&#xff0c;學習文檔&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各種好玩的項目及好用的工具&#xff0c;歡迎關注。 目錄 滲透測試紅隊面試三 六十一、主機被入侵自查解決方案 六十二、NAT&#xff08;網絡地址轉換&#xff…

springboot-web基礎

21.web spring MVC 基于瀏覽器的 B/S 結構應用十分流行。Spring Boot 非常適合 Web 應用開發。可以使用嵌入式 Tomcat、Jetty、 Undertow 或 Netty 創建一個自包含的 HTTP 服務器。一個 Spring Boot 的 Web 應用能夠自己獨立運行&#xff0c;不依賴需 要安裝的 Tomcat&#x…

重構Cursor無限電子郵箱注冊系統的技術實踐

引言 在當今數字化時代&#xff0c;電子郵箱已成為個人和企業網絡身份的基礎。作為開發者&#xff0c;我們往往會遇到需要設計注冊系統的場景&#xff0c;而如何構建一個既安全又用戶友好的郵箱注冊系統&#xff0c;是值得深入探討的話題。本文將圍繞Cursor郵箱系統的技術重構…

2025.05.10京東機考真題算法崗-第三題

?? 點擊直達筆試專欄 ??《大廠筆試突圍》 ?? 春秋招筆試突圍在線OJ ?? 筆試突圍OJ 03. 忍者屋頂之旅 問題描述 LYA是一位身手敏捷的忍者,正在一個古老的村莊進行飛檐走壁的訓練。村莊有兩排房屋,每排從左到右排列著 n n

vscode不能跳轉到同一個工作區的其他文件夾

明白了&#xff0c;你說的“第二種情況”是指&#xff1a; 你先打開的是項目文件夾&#xff08;比如 MyProject&#xff09;&#xff0c;然后通過 VS Code 的“添加文件夾到工作區”功能&#xff0c;把 ThirdPartyLib 文件夾添加進來。 結果&#xff0c;項目代碼里 #include “…

FastAPI 和 MongoDB 實現請求頭參數處理的示例,并在 React 中進行渲染

FastAPI 和 MongoDB 后端 安裝必要的庫 安裝 FastAPI、Uvicorn、Motor&#xff08;用于 MongoDB 的異步驅動&#xff09;和 Pydantic&#xff08;用于數據驗證&#xff09;。 pip install fastapi uvicorn motor pydantic創建 FastAPI 應用 創建一個文件 main.py&#xff0c;并…

技術倫理雙軌認證如何重構AI工程師能力評估體系——基于AAIA框架的技術解析與行業實證研究

引言&#xff1a;AI工程師能力評估的范式轉型 2025年全球人工智能產業呈現出兩大特征&#xff1a;技術迭代加速與監管框架完善。據Gartner數據顯示&#xff0c;全球75%的企業在AI項目部署中遭遇技術倫理混合型難題&#xff0c;傳統單維度技術認證體系已無法滿足產業需求。本文…

03.Golang 切片(slice)源碼分析(二、append實現)

Golang 切片&#xff08;slice&#xff09;源碼分析&#xff08;二、append實現&#xff09; 前言&#xff1a; Golang 切片&#xff08;slice&#xff09;源碼分析&#xff08;一、定義與基礎操作實現&#xff09; 在前面的文章我們介紹了&#xff0c;切片的結構體與創建\擴容…

mysql常用方法

mysql常用方法 一、基本用法 -- MySQL創建唯一索引 CREATE UNIQUE INDEX 索引名 ON 表名(列名1,列名2,...); --也可以使用ALTER TABLE語句給現有表添加唯一索引&#xff08;UNIQUE&#xff09; ALTER TABLE 表名 ADD CONSTRAINT 索引名 UNIQUE KEY(列名1,列名2,...); alter t…