《嵌入式Linux應用編程(六):并發編程基礎:多進程exec函數族及多線程基礎》

一、exec函數族

????????在一個進程里面執行另一個文件

? ? ? ? 本質:將文本區的指令代碼替換成exec要執行的指令

#include <unistd.h>


參數:path:要執行的可執行文件的路徑和名稱
arg:執行該可執行文件時需要傳遞的參數
NULL:參數傳遞結束標志
返回值:錯誤為1,正確不返回

int execlp(const char *file, const char *arg, .../* (char ?*) NULL */);

功能:從PATH指定的系統路徑下尋找該可執行文件

參數:file:需要執行的可執行文件的名稱(系統路徑下已有的文件)

?????????arg:執行該可執行文件時需要傳遞的參數

????????NULL:參數傳遞結束標志

int execle(const char *path, const char *arg, .../*, (char *) NULL, char * const envp[] */);

execle?函數允許自定義環境變量傳遞給新程序。參數?path?為可執行文件的完整路徑,arg?為參數列表,envp?是一個字符串數組,表示新的環境變量(格式為?"KEY=value"),以?NULL?結尾。

int execv(const char *path, char *const argv[]);

execv?與?execl?功能相同,但參數傳遞方式不同。execv?使用字符串數組?argv?傳遞參數(數組末尾需為?NULL),適合動態生成參數的場景。

int execvp(const char *file, char *const argv[]);

execvp?結合了?execv?和?execlp?的特點:從系統路徑查找可執行文件,并通過數組傳遞參數。參數?file?為文件名,argv?為參數數組(含命令自身)。

int execvpe(const char *file, char *const argv[],char *const envp[]);

execvpe?是?execvp?的擴展版本,支持自定義環境變量。參數?envp?為環境變量數組,格式與?execle?相同。非標準函數,需確保系統支持(如 GNU 擴展)。

代碼

#include <stdio.h>int main(void)
{printf("Hello World!\n");return 0;
}

編譯命令為gcc text.c -o hello

#include<stdio.h>
#include<unistd.h>int main(int argc, char const *argv[])
{//execl("./hello", "./hello", NULL);//execl("/bin/ls", "ls", "-l", NULL);//execlp("ls", "ls", "-l", NULL);//char *arg[] = {"ls", "-l", NULL};//execv("/bin/ls", arg);// char *arg[] = {"ls", "-l", NULL};// execvp("ls", arg);return 0;
}

l:list ?列表
p:path ?路徑 : 系統路徑
v:vector 容器
e:env ?環境變量


二、system

system相當于調用了一次fork(),父進程等待子進程運行結束后,在進行運行

不調用system函數接口,實現system的功能


#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>int my_system(char *buff)
{char *arg[10] = {NULL};int i = 0;char cmd[512] = {0};strcpy(cmd, buff);arg[i] = strtok(cmd, " ");while (arg[i] != NULL){printf("arg[%d] = %s\n", i, arg[i]);i++;arg[i] = strtok(NULL, " ");}pid_t pid = fork();if (pid > 0){wait(NULL);}else if (0 == pid){execvp(arg[0], arg);}return 0;}int main(int argc, const char *argv[])
{printf("system : pid = %d\n", getpid());
//	system("./hello");my_system("ls -l");printf("After system\n");return 0;
}

三、線程

1.什么是線程

? ? ? ? 輕量級的線程,可實現多任務的并發。
進程是操作系統資源分配的最小單位;
線程是操作系統任務調度的最小單位。


2.線程的創建

????????線程由某個進程創建。

? ? ? ? 進程創建線程時,會為其分配獨立的8M的獨立的棧區空間

????????線程所在的進程,以及進程中的其他線程,共用進程的堆區、數據區、文本區。


3.線程的調度

? ? ? ? 宏觀并行,微觀串行


4.線程的消亡

? ? ? ? 1)線程退出

? ? ? ? 2)回收線程資源空間


5.進程和線程的區別

????????1)進程

????????資源消耗:

????????????????進程是操作系統資源分配的最小單位;

????????????????資源開銷大,每次創建都需要0-4G的虛擬空間

????????效率方面:

????????????????由操作系統創建,耗時比線程久;跨進程調度比跨線程慢

????????通信方面:

????????????????進程間不能之間通信,需要使用進程間通信機制(IPC)機制

????????安全性角度:

????????????????進程安全性比線程高,各進程空間獨立


????????2)線程

????????資源消耗:

????????????????線程是操作系統任務調度的最小單位。

????????????????資源開銷小,只需要所在進程為其開辟8M的棧區空間

????????效率方面:

????????????????????????由所在進程創建跨進程調度比跨線程調度慢:

????????通信方面:

????????????????????????通信簡單,可以使用線程共享的區域進行通信(比如全局變量)

????????安全性角度:

????????????????????????線程沒有進程安全,一個線程異常可能影響同一進程中所有線程


6.線程的相關編程

1)線程的創建

#include <pthread.h>int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);

功能:

????????創建一個新線程

參數:

????????thread:保存線程ID的變量地址

????????attr:線程屬性的對象地址

????????NULL:按照默認屬性創建

?????????void *(*start_routine) (void *):函數指針,函數名start_routine,指向線程啟動后要執行的任務(線程任務函數)

????????arg:為線程任務函數傳遞的參數

返回值:

????????成功:0

????????失敗:非0

????????pthread—self():獲取當前線程ID號

????????pthread_create是不是linux函數,編譯和鏈接時要加-lpthread

????????進程創建線程后,進程不能先退出,加sleep()

2)線程調度;由操作系統調度

3)線程退出

? ? ? ? I.線程退出

????????????????void pthread_exit(void *retval);

????????????????功能:退出一個線程任務

????????????????參數:

????????????????????????retval:向回收的線程傳遞的參數的地址(NULL表示不傳遞參數)

? ? ? ? II.線程回收

????????????????int pthread_join(pthread t thread, void * *retval).

????????????????功能:回收線程資源空間

????????????????參數:
thread:要回收的線程ID

????????????????????????retvaf用來保存線程退出時傳遞的參數(NULL表示不傳遞參數)

? ? ? ????????? 返回值:

? ? ? ? ????????????????成功:0

? ? ? ? ? ? ? ? ? ? ? ? 失敗-1

? ? ? ? ? ? ? ??III:線程屬性

? ? ? ? ? ? ? ? ? ? ? ? 1.分離屬性:不需要被其他線程回收的線程稱為分離屬性得到線程,將來會被操作系統所回收

? ? ? ? ????????int pthread_detach(pthread_t thread);

? ? ? ????????? 功能:將線程設置為分離屬性的線程

? ? ? ? ? ? ? ? ? ? ? ? 2.非分離屬性:可以被其他線程回收或者結束的線程,稱為非分離屬性的線程(默認屬性:非分離屬性)

? ? ? ? ? ? ? ? IV:線程回收策略:

? ? ? ? ? ? ? ? 1.分離屬性的線程:不需要回收。(沒有空閑的線程可以幫忙回收時)

? ? ? ? ? ? ? ? 2.非分離屬性的線程:pthread_join()阻塞回收

7.線程間通信

? ? ? ? 全局變量通信

? ? ? ? 臨界資源:多個線程可以同時訪問的資源稱為臨界資源:比如,全局變量、共享內存區域等

? ? ? ? 如何解決資源競爭問題:

? ? ? ? ? ? ? ? 1)互斥機制:多個線程訪問臨界資源時,具有排他性訪問的機制(一次只允許一個線程對該臨界資源進行訪問)

? ? ? ? ? ? ? ? 互斥鎖->解決資源競爭問題。

? ? ? ? ? ? ? ? 步驟:

? ? ? ? ? ? ? ? ? ? ? ? 1.創建互斥鎖:pthread_utex_t?

? ? ? ? ? ? ? ? ? ? ? ? 2.初始化互斥鎖:pthread_mutex_init

? ? ? ? ? ? ? ? ? ? ? ? 3.加鎖:pthread_mutex_lock

? ? ? ? ? ? ? ? ? ? ? ? 4.解鎖:pthread_mutex_unlock

? ? ? ? ? ? ? ? ? ? ? ? 5.銷毀鎖:pthread_mutex_destroy

int pthread mutex init(pthread mutex t *restrict mutex.const pthread mutexattr t*restrict attr)

????????功能:初始化互斥鎖

????????參數:mutex:鎖對象地址
attr:鎖的屬性(NULL:默認屬性)

????????返回值:成功:0

? ? ? ? ? ? ? ? ? ? ?失敗:-1

 int pthread_mutex_lock(pthread_mutex_t *mutex);

????????功能:加鎖

int pthread_mutex_unlock(pthread_mutex_t *mutex);

? ? ? ? 功能:解鎖

int pthread_mutex_destroy(pthread_mutex_t *mutex);

? ? ? ? 功能:銷毀鎖


四、線程相關代碼

1.創建線程
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
void *task(void *arg)
{printf("I am thread : tid = %ld\n", pthread_self());
}int main(int argc, char const *argv[])
{pthread_t tid;int ret = pthread_create(&tid, NULL, task, NULL);if(ret != 0){printf("pthread_create error\n");return -1;}sleep(2);return 0;
}

2.讓線程輸出一個學生的信息

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>struct stu
{int id;char name[20];
}Stu;void *task(void *arg)
{struct stu *student = (struct stu *)arg;  printf("%d\n%s\n", student->id, student->name);return NULL;
}int main(int argc, char const *argv[])
{pthread_t tid;struct stu s = {1,"wang"};int ret = pthread_create(&tid, NULL, task, &s);if(ret != 0){printf("pthread_create error\n");return -1;}sleep(1);return 0;
}

3.線程模擬無人機工作

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>void *task1(void *arg)
{ while(1){printf("主控模塊正在運行\n");pthread_exit(NULL);}
}void *task2(void *arg)
{ while(1){printf("控制模塊正在運行\n");pthread_exit(NULL);}
}void *task3(void *arg)
{ while(1){printf("圖像采集模塊正在運行\n");pthread_exit(NULL);}
}void *task4(void *arg)
{ while(1) {printf("圖像發送模塊正在運行\n");pthread_exit(NULL);}
}void *task5(void *arg)
{ while(1){printf("指令接收模塊正在運行\n");pthread_exit(NULL);}
}int main(int argc, char const *argv[])
{pthread_t tid1;pthread_t tid2;pthread_t tid3;pthread_t tid4;pthread_t tid5;int ret1,ret2,ret3,ret4,ret5;ret1 = pthread_create(&tid1, NULL, task1, NULL);ret2 = pthread_create(&tid2, NULL, task2, NULL);ret3 = pthread_create(&tid3, NULL, task3, NULL);ret4 = pthread_create(&tid4, NULL, task4, NULL);ret5 = pthread_create(&tid5, NULL, task5, NULL);if(0 != ret1 && 0 != ret2 && 0 != ret3 && 0 != ret4 && 0 != ret5){printf("pthread_create error\n");return -1;}sleep(1);pthread_join(tid1, NULL);pthread_join(tid2, NULL);pthread_join(tid3, NULL);pthread_join(tid4, NULL);pthread_join(tid5, NULL);return 0;
}

4.加互斥鎖解決資源競爭問題

#include <stdio.h>
#include <pthread.h>int num_g = 0;
pthread_mutex_t mutex;void *task1(void *arg)
{for (int i = 0; i < 100000; i++){pthread_mutex_lock(&mutex);num_g = num_g+1;printf("num_g = %d\n", num_g);pthread_mutex_unlock(&mutex);}
}void *task2(void *arg)
{for (int i = 0; i < 100000; i++){pthread_mutex_lock(&mutex);num_g = num_g+1;printf("num_g = %d\n", num_g);pthread_mutex_unlock(&mutex);}}int main(int argc, const char *argv[])
{pthread_t tid[2];pthread_mutex_init(&mutex, NULL);pthread_create(&tid[0], NULL, task1, NULL);pthread_create(&tid[1], NULL, task2, NULL);pthread_join(tid[0], NULL);pthread_join(tid[1], NULL);pthread_mutex_destroy(&mutex);return 0;
}

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

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

相關文章

【121頁PPT】智慧方案智慧綜合體智能化設計方案(附下載方式)

篇幅所限&#xff0c;本文只提供部分資料內容&#xff0c;完整資料請看下面鏈接 https://download.csdn.net/download/2501_92808859/91654007 資料解讀&#xff1a;【121頁PPT】智慧方案智慧綜合體智能化設計方案 詳細資料請看本解讀文章的最后內容 一、項目概述與智能化總…

Linux網絡基礎(一)

目錄 計算機網絡背景 網絡發展 初識 "協議" 網絡協議初識 協議分層 軟件分層的好處 打電話例子 OSI七層模型 TCP/IP五層(或四層)模型 參考資料 再識協議 為什么要有 TCP/IP 協議&#xff1f; 什么是 TCP/IP 協議&#xff1f; TCP/IP 協議與操作系統的關系(宏觀上&…

MySQL多表查詢案例

多表查詢本文介紹了多表查詢中的表關系概念和操作方法。主要內容包括&#xff1a;1.三種表關系類型&#xff08;一對多、多對多、一對一&#xff09;及其實現方式&#xff1b;2.多表查詢的四種連接方式&#xff08;內連接、左外連接、右外連接、自連接&#xff09;及語法&#…

Dify 從入門到精通(第 36/100 篇):Dify 的插件生態擴展

Dify 從入門到精通&#xff08;第 36/100 篇&#xff09;&#xff1a;Dify 的插件生態擴展 Dify 入門到精通系列文章目錄 第一篇《Dify 究竟是什么&#xff1f;真能開啟低代碼 AI 應用開發的未來&#xff1f;》介紹了 Dify 的定位與優勢第二篇《Dify 的核心組件&#xff1a;從…

【已解決】在Spring Boot工程中,若未識別到resources/db文件夾下的SQL文件

在Spring Boot工程中&#xff0c;若未識別到resources/db文件夾下的SQL文件&#xff0c;通常與資源路徑配置、構建工具設置或代碼加載方式有關。以下是逐步排查和解決方案&#xff1a;??1. 確認SQL文件存放路徑??Spring Boot默認從類路徑&#xff08;classpath:&#xff09…

【Java】網絡編程(4)

1. 再談 UDP 報文長度&#xff1a;也是 2 個字節&#xff0c; 0 - 65535&#xff0c;也就是 64 kb。這表示一個 UDP 數據包一次最多只能傳輸 64 kb 的數據校驗和&#xff1a;驗證數據是否在傳輸過程中發生修改。數據在傳輸過程中可能受到信號干擾&#xff0c;發生 “比特翻轉”…

QT(事件)

一、事件前言事件是QT的三大機制之一&#xff0c;一定程度上信號和槽也屬于事件的一種 QT中的事件指哪些&#xff1a;窗口關閉&#xff0c;窗口顯示&#xff0c;敲擊鍵盤&#xff0c;點擊鼠標左鍵、鼠標右鍵、鼠標滾輪&#xff0c;文件拖放等等1、事件循環QT中的所有事件&#…

基于 Vue2+Quill 的富文本編輯器全方案:功能實現與樣式優化

在 Web 開發中&#xff0c;富文本編輯器是內容管理系統、博客平臺等應用的核心組件。本文將詳細介紹如何基于 Vue 和 Quill 構建一個功能完善、樣式精美的富文本編輯器&#xff0c;重點解決字體字號選項冗長、樣式不美觀及功能完整性問題&#xff0c;提供可直接部署使用的完整方…

C#內嵌字符串格式化輸出

內嵌字符串格式輸出 double speedOfLight 299792.458;System.Globalization.CultureInfo.CurrentCulture System.Globalization.CultureInfo.GetCultureInfo("nl-NL"); string messageInCurrentCulture $"The speed of light is {speedOfLight:N3} km/s.&quo…

ThreeJS程序化生成城市大場景底座(性能測試)

一、簡介基于矢量geojson數據構建建筑、植被、道路等&#xff0c;實現城市場景底座。涉及渲染的性能優化無非就是眾所周知的那些事兒。視錐剔除、mesh合并、減少draw call、四叉樹、八叉樹、數據壓縮、WebWorker、著色器優化等。下面是對東莞市數十萬建筑以及海量3D樹的渲染測試…

?電風扇離線語音芯片方案設計與應用場景:基于 8 腳 MCU 與 WTK6900P 的創新融合

?電風扇離線語音芯片方案設計與應用場景&#xff1a;基于 8 腳 MCU 與 WTK6900P 的創新融合一、引言在智能家居領域蓬勃發展的當下&#xff0c;用戶對于家電產品的智能化和便捷性需求日益增長。傳統的電風扇控制方式&#xff0c;如按鍵操作或遙控器控制&#xff0c;在某些場景…

(第四篇)spring cloud之Consul注冊中心

目錄 一、介紹 二、安裝 三、整合代碼使用 1、創建服務提供者8006 2、創建服務消費者80 3、Eureka、zookeeper和consul的異同點 一、介紹 Consul 是一套開源的分布式服務發現和配置管理系統&#xff0c;由 HashiCorp 公司用 Go 語言開發。它提供了微服務系統中的服務治理…

NAT 和 PNAT

核心概念與背景 IPv4 地址枯竭&#xff1a; IPv4 地址空間有限&#xff08;約 42.9 億個&#xff09;&#xff0c;早已分配殆盡。NAT/PNAT 是緩解此問題的最重要、最廣泛部署的技術。私有 IP 地址空間&#xff1a; IANA 保留了三個 IPv4 地址段專供私有網絡內部使用&#xff08…

windows系統創建FTP服務

一丶開啟FTP功能 控制面板->程序與功能->啟用或關閉windows功能->Internet Information Services->勾選FTP服務器二丶創建FTP服務 1丶控制面板->windows工具->Internet Information Services (IIS) 管理器2丶網站->添加FTP站點->輸入對應內容3丶點擊新…

DeepSeek補全IBM MQ 9.4 REST API 執行命令的PPT

DeepSeek補全了我在網上找到的PPT的一頁內容&#xff0c;幫了大忙了。人機協同&#xff0c;人工智能可以協助人更好的做事。下面的內容是講解IBM MQ REST API 執行IBM MQ命令的PPT: MQSC for REST Tailored RESTful support for individual MQ objects and actions are in the …

【swift】SwiftUI動畫卡頓全解:GeometryReader濫用檢測與Canvas繪制替代方案

SwiftUI動畫卡頓全解&#xff1a;GeometryReader濫用檢測與Canvas繪制替代方案一、GeometryReader的性能陷阱深度解析1. 布局計算機制2. 動畫中的災難性表現二、GeometryReader濫用檢測系統1. 靜態代碼分析器2. 運行時性能監控三、Canvas繪制優化方案1. 基礎Canvas實現2. 性能優…

悄悄話、合唱層次感:聲網空間音頻解鎖語聊新玩法

作為語聊房主播&#xff0c;我曾覺得線上相聚差點意思。多人開麥時聲音混雜&#xff0c;互動缺真實感&#xff0c;觀眾留不住&#xff0c;自己播著也沒勁。直到平臺接入聲網空間音頻&#xff0c;一切改觀&#xff0c;觀眾說像在真實房間聊天&#xff0c;留存率漲 35%&#xff0…

【工具】多圖裁剪批量處理工具

文章目錄工具核心功能亮點1. 批量上傳與智能管理2. 精準直觀的裁剪控制3. 一鍵應用與批量處理為什么這個工具能提升你的工作效率&#xff1f;統一性與一致性保證節省90%以上的時間專業級功能&#xff0c;零學習成本實際應用場景電子商務攝影工作內容創作教育領域技術優勢完全在…

如何提升需求分析能力

要系統性地提升需求分析能力&#xff0c;核心在于實現從一個被動的“需求記錄員”&#xff0c;向一個主動的、價值驅動的“業務問題解決者”的深刻轉型。要完成這一蛻變&#xff0c;必須在五個關鍵領域進行系統性的修煉與實踐&#xff1a;培養“穿透表象”的系統思維能力、掌握…

另類的pdb恢復方式

cdb中有pdb1,pdb2 需求&#xff1a;希望將在線熱備份pdb1的備份集a&#xff0c;恢復成pdb3&#xff0c;使得cdb中有pdb1,2,3 參考到的&#xff1a;RMAN備份恢復典型案例——跨平臺遷移pdb - 墨天輪 ORA-65122: Pluggable Database GUID Conflicts With The GUID Of An Existi…