线程(Thread)
一、概念
线程:线程是一个轻量级的进程
二、线程的创建
1、线程的空间
(1)进程的空间包括:系统数据段、数据段、文本段
(2) 线程位于进程空间内部
(3) 栈区独享、与进程共享文本段、数据段、堆区

2、线程与进程的关系
进程:进程是操作系统资源分配的最小单元(进程:文本段+数据段+系统数据段)
线程:线程是CPU任务调度的最小单元
(1)每个线程独立拥有8M(默认)栈空间
(2)其余的文本段、数据段、堆区都是与进程及进程内的其余线程共享的
三、线程的调度
(1)线程的调度等价于进程的调度(宏观并行,微观串行)
线程之间宏观并行,微观串行;所以线程在执行的过程中,会出现以下情况:
情况一:线程1先执行,线程二后执行
情况二:线程2先执行,线程1后执行
情况三:线程2执行一半后执行线程1,线程1执行一半后执行线程2,即二者交叉执行(2)线程是CPU任务调度的最小单元
四、线程的消亡
(1)与进程消亡保持一致,进程结束时不论线程处于什么状态,线程被强制结束
(2)僵尸线程:等到线程结束需要回收线程空间,否则会产生僵尸线程
五、多进程vs多线程
1、执行效率
多线程 > 多进程
线程 间任务的切换是在同一片进程空间内部完成任务切换,资源开销小
进程 间任务的切换需要映射到不同的物理地址空间,频繁切换资源开销大
2、多任务间通信的实现
多线程 > 多进程
多线程 拥有共享空间(多个线程位于一个进程内,共享该进程的数据区、文本区),通信更加方便
多进程 没有共享空间(进程间是独立的),需要更为复杂的方法实现多进程间通信
3、多任务通信机制的复杂程度
多线程 > 多进程
多线程 操作全局变量会引入资源竞争,需要加锁来解决
多进程 没有资源竞争
4、安全性
多进程 > 多线程
线程 异常崩溃导致进程崩溃,该进程中的其余线程异常结束
进程 异常结束,不会影响其余进程
六、线程相关的函数接口
pthread_create == fork
pthread_exit == exit
pthread_join == wait
1、pthread_creat
man 3 pthread_create
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
功能:
在调用函数的进程中创建一个线程
参数:
thread:存放线程ID空间的首地址
attr:线程的属性
start_routine:线程函数的入口
void *(*start_routine) (void *)函数指针,返回值类型void*,参数void*,*start_routine:函数首地址(函数名本身就是函数首地址)
arg:传入线程函数的参数(给start_routine函数传的参数)
返回值:
成功返回0
失败返回错误数字
#include <stdio.h>
#include "public.h" //头文件中包含pthread_creat的头文件,但是编译时还需使用 -lpthread(链接头文件)//cc src/main.c -o ./build/a.out -I./include -lpthreadvoid *thread_fun(void *arg)
{printf("线程(TID:%#x)开始执行\n", (unsigned int)pthread_self()); //pthread_self获取线程IDreturn NULL;
}int main(int argc, const char **argv)
{pthread_t tid1;pthread_t tid2;pthread_t tid3;int ret = 0;ret = pthread_create(&tid1, NULL, thread_fun, NULL);if (ret != 0){ERR_MSG("fail to pthread_create");return -1;}ret = pthread_create(&tid2, NULL, thread_fun, NULL);if (ret != 0){ERR_MSG("fail to pthread_create");return -1;}ret = pthread_create(&tid3, NULL, thread_fun, NULL);if (ret != 0){ERR_MSG("fail to pthread_create");return -1;}while (1){}return 0;
}
2、pthread_exit
man 3 pthread_exit
void pthread_exit(void *retval);
功能:
线程退出
参数:
retval:线程退出的值
返回值:
缺省
3、pthread_join
man 3 pthread_join
int pthread_join(pthread_t thread, void **retval);
功能:
回收线程空间
参数:
thread:要回收的线程的ID
retval:存放线程结束状态指针空间的首地址
返回值:
成功返回0
失败返回错误码
注意:
1.pthread_join具有阻塞功能,线程不结束,一直等到线程结束,回收到线程空间再继续向下执 行
2.pthread_join具有同步功能
#include <stdio.h>
#include "public.h"#if 0
int main(int argc,const char** argv)
{pthread_t tid1;pthread_t tid2;pthread_t tid3;pthread_create(&tid1, NULL, thread1, NULL);pthread_create(&tid2, NULL, thread2, NULL);pthread_create(&tid3, NULL, thread3, NULL);pthread_join(tid1, NULL);pthread_join(tid2, NULL);pthread_join(tid3, NULL); return 0;
}#endif#if 0
void *thread1(void *arg)
{printf("线程1(TID:%#lx)正在执行\n", pthread_self());return NULL;
}void *thread2(void *arg)
{printf("线程2(TID:%#lx)正在执行\n", pthread_self());return NULL;
}void *thread3(void *arg)
{printf("线程3(TID:%#lx)正在执行\n", pthread_self());return NULL;
}int main(int argc, const char **argv)
{pthread_t tid[3];int i = 0;int a[3] = {1, 2, 3};void *(*pfun[3])(void *) = {thread1, thread2, thread3}; //函数指针数组for (i = 0; i < 3; i++){pthread_create(&tid[i], NULL,pfun[i],NULL);}for (i = 0; i < 3; i++){pthread_join(tid[i], NULL);}#endif#if 1
void *thread(void* arg)
{int* pnum = arg;printf("线程%d(TID:%#lx)正在执行\n", *pnum, pthread_self());return NULL;
}int main(int argc, const char **argv)
{pthread_t tid[3];int i = 0;int a[3] = {1, 2, 3};for (i = 0; i < 3; i++){//pthread_create(&tid[i], NULL,thread,&i); //error 所有线程共享同一个 i 的地址,因此当线程函数 thread 访问 &i 时,获取的值可能是循环结束后 i 的最终值(即 3),而不是创建线程时的值。这会导致所有线程可能接收到相同的值3,而不是预期的 0、1、2pthread_create(&tid[i], NULL,thread,&a[i]); //right 数组 a 的值是固定的({1, 2, 3}),每个线程会接收到数组 a 中对应索引的值。由于每个线程接收的是数组 a 中不同元素的地址,线程函数 thread 可以正确地访问到 1、2、3 这些值}for (i = 0; i < 3; i++){pthread_join(tid[i], NULL);}
#endifreturn 0;
}
七、线程的分离属性
1、概念
线程结束后,操作系统自动回收线程空间,无需调用pthread_join来回收线程空间
2、函数接口
man 3 pthread_attr_setdetachstate
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
功能:
将线程属性中加入分离属性
在这种状态下,线程终止时会自动释放其资源,无需其他线程调用 pthread_join()
参数:
attr:线程属性空间首地址
detachstate: PTHREAD_CREATE_DETACHED 分离属性 PTHREAD_CREATE_JOINABLE 加入属性
返回值:
成功返回0
失败返回错误码
pthread_attr_setdetachstate需要用到的辅助函数
//对attr进行初始化
int pthread_attr_init(pthread_attr_t *attr);
//销毁attrint pthread_attr_destroy(pthread_attr_t *attr);
#include <stdio.h>
#include "public.h"#if 1
int is_exit = 0;void* thread1(void* arg)
{int cnt = 0 ;while(!is_exit){if(cnt == 2){printf("采集线程正在执行!\n");cnt = 0;}cnt++;usleep(500000);}return NULL;
}
void* thread2(void* arg)
{int cnt = 0 ;while(!is_exit){if(cnt == 4){printf("显示线程正在执行!\n");cnt = 0;}cnt++;usleep(500000);}return NULL;
}
void* thread3(void* arg)
{int cnt = 0 ;while(!is_exit){if(cnt == 10){printf("存储线程正在执行!\n");cnt = 0;}cnt++;usleep(500000); }return NULL;
}
void* thread4(void* arg)
{int cnt = 0 ;while(!is_exit){if(cnt == 20){printf("日志线程正在执行!\n");cnt = 0;}cnt++;usleep(500000); //同样是睡眠10秒但这样的操作让单位时间缩短了,避免了线程正在睡眠时线程结束的情况//sleep(10) }return NULL;
}
int main(int argc,const char** argv)
{int i = 0;pthread_t tid[4];pthread_attr_t attr;void*(*pfun[4])(void*) = {thread1,thread2,thread3,thread4};char tmpbuff[1024] = {0};pthread_attr_init(&attr);pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);for(i = 0;i < 4;i++){pthread_create(&tid[i],&attr, pfun[i], NULL);}pthread_attr_destroy(&attr);while(1){ gets(tmpbuff);if(0 == strcmp(tmpbuff,".quit")){is_exit = 1;break;}}sleep(1); //进程睡眠1秒,确保线程完全执行过 return 0;
}#endif
相关文章:
线程(Thread)
一、概念 线程:线程是一个轻量级的进程 二、线程的创建 1、线程的空间 (1)进程的空间包括:系统数据段、数据段、文本段 (2) 线程位于进程空间内部 (3) 栈区独享、与进程共享文本段、…...
AI军备竞赛2025:GPT-4.5的“情商革命”、文心4.5的开源突围与Trae的代码革命
AI军备竞赛2025:GPT-4.5的“情商革命”、文心4.5的开源突围与Trae的代码革命 ——一场重塑人类认知边界的技术战争 一、OpenAI的“感性觉醒”:GPT-4.5的颠覆与争议 1.1 从“冷面学霸”到“温柔导师”:AI的情商跃迁 当用户输入“朋友放鸽子&…...
DeepSeek + 自由职业 发现新大陆,从 0 到 1 全流程跑通商业 IP
DeepSeek 自由职业 发现新大陆,从 0 到 1 全流程跑通商业 IP 商业定位1. 商业定位分析提示词2. 私域引流策略提示词3. 变现模型计算器提示词4. 对标账号分析提示词5. 商业IP人设打造提示词6. 内容选题策略提示词7. 用户人群链分析提示词8. 内容布局与转化路径设计提…...
Java进阶——常用工具类
日常开发中,Arrays、Collections 和 Objects 是非常实用的工具类,提供了丰富的功能,从而可以更高效地处理数组、集合和对象。本文将详细介绍这三个工具类的重要知识细节。 本文目录 一、 Arrays数组转集合并行排序优化Stream 支持 二、 Colle…...
【考试大纲】高级系统架构设计师考试大纲
目录 引言一、 考试说明1.考试目标2.考试要求3.考试科目设置二、 考试范围考试科目1:系统架构设计综合知识考试科目2:系统架构设计案例分析考试科目3:系统架构设计论文引言 最新的系统架构设计师考试大纲出版于 2022 年 11 月,本考试大纲基于此版本整理。 一、 考试说明…...
上位机知识篇---四种CPU架构交叉编译
文章目录 前言一、四种 CPU 架构1. x86/x86_64指令集位宽:应用场景编译工具 2. ARM指令集位宽:应用场景编译工具 3. MIPS指令集位宽应用场景编译工具 4. RISC-V指令集位宽应用场景编译工具 二、交叉编译1. 什么是交叉编译?定义应用场景 2. 交…...
隐式转换为什么导致索引失效
SELECT * FROM users WHERE id 123;这条语句失效的原因就是id是int类型的主键,比较的时候把id从int转化为字符串来比较了,而字符串的比较规则和int的比较规则明显不同,字符串是字典序比较的,还涉及到数据的长度,那为什…...
【含文档+PPT+源码】基于过滤协同算法的旅游推荐管理系统设计与实现
项目介绍 本课程演示的是一款基于过滤协同算法的旅游推荐管理系统设计与实现,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含:项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套…...
SpringBoot @Value 注解使用
Value 注解用于将配置文件中的属性值注入到Spring管理的Bean中。 1. 基本用法 Value 可以直接注入配置文件中的属性值。 配置文件 (application.properties 或 application.yml) 配置文件定义需要注入的数据。 consumer:username: lisiage: 23hobby: sing,read,sleepsubje…...
Spring Boot 3.x 系列【3】Spring Initializr快速创建Spring Boot项目
有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot版本3.0.3 源码地址:https://gitee.com/pearl-organization/study-spring-boot3 文章目录 前言安装JDK 17创建Spring Boot 项目 方式1:网页在线生成方式2&#…...
高频 SQL 50 题(基础版)_1667. 修复表中的名字
高频 SQL 50 题(基础版)_1667. 修复表中的名字 select user_id ,concat(upper(substring(name,1,1)),lower(substring(name,2))) as name from Users order by user_id...
Windwos10 系统没有微软商店(Microsoft Store)怎么办?
操作方法 管理员身份打开power shell , 输入 Get-AppxPackage -AllUsers Microsoft.WindowsStore* | Foreach {Add-AppxPackage -DisableDevelopmentMode -Register “ ( ( (_.InstallLocation)\AppXManifest.xml”} 按下enter按键,就OK了...
c++同步机制
总结 多线程访问共享数据时需要加锁 多线程数据竞争 假如有一个变量shared_variable被10个线程共享,每个线程在循环中对shared_variable进行 1000 次累加操作,我们期望最终值为10000。 #include <iostream> #include <thread> #include …...
RuoYi框架介绍,以及如何基于Python使用RuoYi框架
若依框架(RuoYi)是一款基于Spring Boot和Vue.js的开源快速开发平台,广泛应用于企业级应用开发。它提供了丰富的功能模块和代码生成工具,帮助开发者快速搭建后台管理系统。 主要特点 前后端分离:前端采用Vue.js&#x…...
Go 语言环境安装
1.go官网下载安装包 All releases - The Go Programming Language 双击安装,一路下一步 2.安装完后查看版本 打开cmd 输入 以下 ,查看语言版本 go version 查看环境变量是否自动设置成功...
vector 面试点总结
ps:部分内容使用“AI”查询 一、入门 1、什么是vector 动态数组容器,支持自动扩容、随机访问和连续内存存储。 2、怎么创建-初始化vector std::vector<int> v; // 创建空vectorstd::vector<int> v {1, 2, 3}; // 直接初始化std::vec…...
Java 8 新特性
Java 8 引入了一系列重要的新特性,极大地增强了 Java 语言的功能,尤其是在 函数式编程、流处理、日期时间 API 和 默认方法 等方面。这些新特性不仅提升了代码的可读性和简洁性,还改善了并发处理的性能。以下是 Java 8 主要新特性的详细说明。…...
知识库技术选型:主流Embedding模型特性对比
知识库技术选型:主流Embedding模型特性对比 1. 知识库与大模型结合的背景 知识库是存储和管理结构化知识的系统,广泛应用于问答系统、推荐系统和搜索引擎等领域。随着大语言模型(LLM)的发展,知识库与大模型的结合成为…...
CAN总线通信协议学习2——数据链路层之帧格式
1 帧格式 帧格式可理解为定义了传输的数据(叫报文)应该“长什么样”来传输,也为后续设定一些规则如错误检查机制提供了思路。 首先,帧格式可分为以下5种类型: PS:CAN总线任意一个设备可当收也可当发&#…...
基于ArcGIS Pro、Python、USLE、INVEST模型等多技术融合的生态系统服务构建生态安全格局高阶应用
文字目录 前言第一章、生态安全评价理论及方法介绍一、生态安全评价简介二、生态服务能力简介三、生态安全格局构建研究方法简介 第二章、平台基础一、ArcGIS Pro介绍二、Python环境配置 第三章、数据获取与清洗一、数据获取:二、数据预处理(ArcGIS Pro及…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...
