当前位置: 首页 > news >正文

线程(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);  
       //销毁attr

        int 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)

一、概念 线程&#xff1a;线程是一个轻量级的进程 二、线程的创建 1、线程的空间 &#xff08;1&#xff09;进程的空间包括&#xff1a;系统数据段、数据段、文本段 &#xff08;2&#xff09; 线程位于进程空间内部 &#xff08;3&#xff09; 栈区独享、与进程共享文本段、…...

AI军备竞赛2025:GPT-4.5的“情商革命”、文心4.5的开源突围与Trae的代码革命

AI军备竞赛2025&#xff1a;GPT-4.5的“情商革命”、文心4.5的开源突围与Trae的代码革命 ——一场重塑人类认知边界的技术战争 一、OpenAI的“感性觉醒”&#xff1a;GPT-4.5的颠覆与争议 1.1 从“冷面学霸”到“温柔导师”&#xff1a;AI的情商跃迁 当用户输入“朋友放鸽子&…...

DeepSeek + 自由职业 发现新大陆,从 0 到 1 全流程跑通商业 IP

DeepSeek 自由职业 发现新大陆&#xff0c;从 0 到 1 全流程跑通商业 IP 商业定位1. 商业定位分析提示词2. 私域引流策略提示词3. 变现模型计算器提示词4. 对标账号分析提示词5. 商业IP人设打造提示词6. 内容选题策略提示词7. 用户人群链分析提示词8. 内容布局与转化路径设计提…...

Java进阶——常用工具类

日常开发中&#xff0c;Arrays、Collections 和 Objects 是非常实用的工具类&#xff0c;提供了丰富的功能&#xff0c;从而可以更高效地处理数组、集合和对象。本文将详细介绍这三个工具类的重要知识细节。 本文目录 一、 Arrays数组转集合并行排序优化Stream 支持 二、 Colle…...

【考试大纲】高级系统架构设计师考试大纲

目录 引言一、 考试说明1.考试目标2.考试要求3.考试科目设置二、 考试范围考试科目1:系统架构设计综合知识考试科目2:系统架构设计案例分析考试科目3:系统架构设计论文引言 最新的系统架构设计师考试大纲出版于 2022 年 11 月,本考试大纲基于此版本整理。 一、 考试说明…...

上位机知识篇---四种CPU架构交叉编译

文章目录 前言一、四种 CPU 架构1. x86/x86_64指令集位宽&#xff1a;应用场景编译工具 2. ARM指令集位宽&#xff1a;应用场景编译工具 3. MIPS指令集位宽应用场景编译工具 4. RISC-V指令集位宽应用场景编译工具 二、交叉编译1. 什么是交叉编译&#xff1f;定义应用场景 2. 交…...

隐式转换为什么导致索引失效

SELECT * FROM users WHERE id 123;这条语句失效的原因就是id是int类型的主键&#xff0c;比较的时候把id从int转化为字符串来比较了&#xff0c;而字符串的比较规则和int的比较规则明显不同&#xff0c;字符串是字典序比较的&#xff0c;还涉及到数据的长度&#xff0c;那为什…...

【含文档+PPT+源码】基于过滤协同算法的旅游推荐管理系统设计与实现

项目介绍 本课程演示的是一款基于过滤协同算法的旅游推荐管理系统设计与实现&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 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项目

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Spring Boot版本3.0.3 源码地址&#xff1a;https://gitee.com/pearl-organization/study-spring-boot3 文章目录 前言安装JDK 17创建Spring Boot 项目 方式1&#xff1a;网页在线生成方式2&#…...

高频 SQL 50 题(基础版)_1667. 修复表中的名字

高频 SQL 50 题&#xff08;基础版&#xff09;_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 &#xff0c; 输入 Get-AppxPackage -AllUsers Microsoft.WindowsStore* | Foreach {Add-AppxPackage -DisableDevelopmentMode -Register “ ( ( (_.InstallLocation)\AppXManifest.xml”} 按下enter按键&#xff0c;就OK了...

c++同步机制

总结 多线程访问共享数据时需要加锁 多线程数据竞争 假如有一个变量shared_variable被10个线程共享&#xff0c;每个线程在循环中对shared_variable进行 1000 次累加操作&#xff0c;我们期望最终值为10000。 #include <iostream> #include <thread> #include …...

RuoYi框架介绍,以及如何基于Python使用RuoYi框架

若依框架&#xff08;RuoYi&#xff09;是一款基于Spring Boot和Vue.js的开源快速开发平台&#xff0c;广泛应用于企业级应用开发。它提供了丰富的功能模块和代码生成工具&#xff0c;帮助开发者快速搭建后台管理系统。 主要特点 前后端分离&#xff1a;前端采用Vue.js&#x…...

Go 语言环境安装

1.go官网下载安装包 All releases - The Go Programming Language 双击安装,一路下一步 2.安装完后查看版本 打开cmd 输入 以下 ,查看语言版本 go version 查看环境变量是否自动设置成功...

vector 面试点总结

ps&#xff1a;部分内容使用“AI”查询 一、入门 1、什么是vector 动态数组容器&#xff0c;支持自动扩容、随机访问和连续内存存储。 2、怎么创建-初始化vector std::vector<int> v; // 创建空vectorstd::vector<int> v {1, 2, 3}; // 直接初始化std::vec…...

Java 8 新特性

Java 8 引入了一系列重要的新特性&#xff0c;极大地增强了 Java 语言的功能&#xff0c;尤其是在 函数式编程、流处理、日期时间 API 和 默认方法 等方面。这些新特性不仅提升了代码的可读性和简洁性&#xff0c;还改善了并发处理的性能。以下是 Java 8 主要新特性的详细说明。…...

知识库技术选型:主流Embedding模型特性对比

知识库技术选型&#xff1a;主流Embedding模型特性对比 1. 知识库与大模型结合的背景 知识库是存储和管理结构化知识的系统&#xff0c;广泛应用于问答系统、推荐系统和搜索引擎等领域。随着大语言模型&#xff08;LLM&#xff09;的发展&#xff0c;知识库与大模型的结合成为…...

CAN总线通信协议学习2——数据链路层之帧格式

1 帧格式 帧格式可理解为定义了传输的数据&#xff08;叫报文&#xff09;应该“长什么样”来传输&#xff0c;也为后续设定一些规则如错误检查机制提供了思路。 首先&#xff0c;帧格式可分为以下5种类型&#xff1a; PS&#xff1a;CAN总线任意一个设备可当收也可当发&#…...

基于ArcGIS Pro、Python、USLE、INVEST模型等多技术融合的生态系统服务构建生态安全格局高阶应用

文字目录 前言第一章、生态安全评价理论及方法介绍一、生态安全评价简介二、生态服务能力简介三、生态安全格局构建研究方法简介 第二章、平台基础一、ArcGIS Pro介绍二、Python环境配置 第三章、数据获取与清洗一、数据获取&#xff1a;二、数据预处理&#xff08;ArcGIS Pro及…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...