C语言:多线程
多线程概述
定义
多线程是指在一个程序中可以同时运行多个不同的执行路径(线程),这些线程可以并发或并行执行。并发是指多个线程在宏观上同时执行,但在微观上可能是交替执行的;并行则是指多个线程真正地同时执行,通常需要多核处理器的支持。
优点
-
提高程序性能:充分利用多核处理器的资源,减少程序的执行时间。例如,在一个图像处理程序中,可以使用多个线程分别处理不同区域的图像,从而加快处理速度。
-
增强响应性:在图形用户界面(GUI)程序中,使用多线程可以避免主线程被耗时的操作阻塞,保证界面的流畅性和响应性。例如,当用户点击一个按钮触发一个耗时的计算任务时,可以使用一个新的线程来执行该任务,而主线程继续处理用户的其他操作。
-
提高资源利用率:在等待某些操作(如I/O操作)完成时,线程可以让出CPU资源,让其他线程继续执行,从而提高CPU的利用率。
缺点
-
线程安全问题:多个线程同时访问共享资源时,可能会导致数据竞争、不一致等问题。例如,多个线程同时对一个共享变量进行读写操作,可能会导致数据的错误更新。
-
上下文切换开销:线程的切换需要保存和恢复线程的上下文信息,这会带来一定的开销,尤其是在频繁切换线程的情况下。
-
死锁问题:多个线程在竞争资源时,可能会出现死锁的情况,即每个线程都在等待其他线程释放资源,从而导致所有线程都无法继续执行。
多线程的实现
操作系统层面的支持
现代操作系统都提供了对多线程的支持,不同的操作系统有不同的线程实现方式。常见的线程库有:
-
POSIX线程库(pthread):是一种跨平台的线程库,广泛应用于Unix、Linux和macOS等操作系统。它提供了一组函数来创建、管理和同步线程。
-
Windows线程库:Windows操作系统提供了自己的线程库,通过
CreateThread等函数来创建和管理线程。
C语言中的多线程实现
(以pthread线程的创建和销毁为例)
#include <stdio.h>
#include <pthread.h>// 线程函数
void* thread_function(void* arg) {printf("This is a new thread.\n");return NULL;
}int main() {pthread_t thread;// 创建线程if (pthread_create(&thread, NULL, thread_function, NULL) != 0) {perror("pthread_create");return 1;}// 等待线程结束if (pthread_join(thread, NULL) != 0) {perror("pthread_join");return 1;}printf("Main thread: New thread has finished.\n");return 0;
}
代码解释:
-
pthread_create:用于创建一个新的线程,第一个参数是指向线程标识符的指针,第二个参数是线程的属性,通常设为NULL,第三个参数是线程函数的指针,第四个参数是传递给线程函数的参数。 -
pthread_join:用于等待指定的线程结束,并回收其资源。
线程的同步和互斥
为了避免多个线程同时访问共享资源时出现数据竞争等问题,需要使用同步和互斥机制。常见的同步和互斥机制有互斥锁(Mutex)、条件变量(Condition Variable)和信号量(Semaphore)等。
互斥锁示例:
#include <stdio.h>
#include <pthread.h>// 定义互斥锁
pthread_mutex_t mutex;
// 共享资源
int shared_variable = 0;// 线程函数
void* thread_function(void* arg) {// 锁定互斥锁pthread_mutex_lock(&mutex);// 访问共享资源shared_variable++;printf("Thread: shared_variable = %d\n", shared_variable);// 解锁互斥锁pthread_mutex_unlock(&mutex);return NULL;
}int main() {pthread_t thread1, thread2;// 初始化互斥锁pthread_mutex_init(&mutex, NULL);// 创建线程pthread_create(&thread1, NULL, thread_function, NULL);pthread_create(&thread2, NULL, thread_function, NULL);// 等待线程结束pthread_join(thread1, NULL);pthread_join(thread2, NULL);// 销毁互斥锁pthread_mutex_destroy(&mutex);return 0;
}
代码解释:
-
pthread_mutex_init:初始化互斥锁。 -
pthread_mutex_lock:锁定互斥锁,如果互斥锁已经被其他线程锁定,则当前线程会阻塞。 -
pthread_mutex_unlock:解锁互斥锁,允许其他线程锁定该互斥锁。 -
pthread_mutex_destroy:销毁互斥锁,释放相关资源。
多线程编程的注意事项
线程安全
在多线程编程中,要确保对共享资源的访问是线程安全的。可以通过使用同步和互斥机制来实现线程安全,避免数据竞争和不一致的问题。
死锁避免
死锁是多线程编程中常见的问题,为了避免死锁,可以采用以下方法:
-
按顺序加锁:确保所有线程按照相同的顺序获取锁,避免循环等待。
-
限时加锁:在获取锁时设置一个超时时间,如果在规定时间内无法获取锁,则放弃锁的获取,避免线程一直阻塞。
资源管理
在多线程编程中,要注意资源的管理,避免资源泄漏。例如,在使用完互斥锁、条件变量等资源后,要及时销毁。
多线程的应用场景
服务器端编程
在服务器端编程中,多线程可以用于处理多个客户端的请求。每个客户端的请求可以由一个独立的线程来处理,从而提高服务器的并发处理能力。
并行计算
在科学计算、图像处理等领域,多线程可以用于并行计算,将一个大的任务分解成多个小的子任务,由多个线程同时执行,从而加快计算速度。
图形用户界面(GUI)编程
在GUI编程中,多线程可以用于处理耗时的操作,避免主线程被阻塞,保证界面的流畅性和响应性。例如,在一个文件下载的GUI程序中,可以使用一个新的线程来执行文件下载任务,而主线程继续处理用户的其他操作。
相关文章:
C语言:多线程
多线程概述 定义 多线程是指在一个程序中可以同时运行多个不同的执行路径(线程),这些线程可以并发或并行执行。并发是指多个线程在宏观上同时执行,但在微观上可能是交替执行的;并行则是指多个线程真正地同时执行&…...
livekit ICE连接失败的一些总结
在使用livekit做的项目过程中碰到了一些ICE连接失败的问题, 一个时在同网段的局域网下 ,livekti服务和客户端不能联通,后来发现是服务端是多网卡,通过网络抓包才知道服务端在stun binding的时候使用了错误的网卡,在co…...
Python神经网络1000个案例算法汇总
【2025最新版】Python神经网络优化1000个案例算法汇总(长期更新版) 本文聚焦神经网络、优化算法,神经网络改进,优化算法改进,优化算法优化神经网络权重、超参数等,现在只需订阅即可拥有,简直是人工智能初学者的天堂。…...
某地81栋危房自动化监测试点项目
1. 项目简介 房屋进入老龄化阶段后,结构安全风险越来越大。近10年来,每年都会产生房屋倒塌人员伤亡的重大安全事故。调研分析显示,老旧房屋结构安全风险管理的有效路径为,通过“人防技防”的组合模式,对房屋安全风险进…...
远程装个Jupyter-AI协作笔记本,Jupyter容器镜像版本怎么选?安装部署教程
通过Docker下载Jupyter镜像部署,输入jupyter会发现 有几个版本,不知道怎么选?这几个版本有什么差别? 常见版本有: jupyter/base-notebookjupyter/minimal-notebookjupyter/scipy-notebookjupyter/datascience-notebo…...
python文件的基本操作和文件读写
目录 文件的基本操作 文件读写 文件的基本操作 Python 中对文件的基本操作主要包括打开文件、读取文件、写入文件和关闭文件等操作。下面是一个简单的示例: 打开文件: file open(example.txt, r) # 使用 open() 函数打开一个名为 example.txt 的文…...
山东大学软件学院项目创新实训开发日志(4)之中医知识问答数据存储、功能结构、用户界面初步设计
目录 数据库设计: 功能设计: 用户界面: 数据库设计: --对话表 (1个对话包含多条消息) CREATE TABLE conversations ( conv_id VARCHAR(36) PRIMARY KEY, -- 对话ID user_id VARCHAR(36) NOT NULL, -- 所属用户 title VARCHAR(100), -- 对话…...
20.思科交换机二层链路聚合的详细配置命令解析
思科交换机二层链路聚合的详细配置命令解析 一、PAgP协议的配置SW1的配置SW2的配置二、LACP标准协议三、配置聚合组的带宽和速率四、确保所有接口的双工模式和速率一致五、故障排除和监控在Cisco设备上配置链路聚合(也称为端口通道或EtherChannel)可以增强网络连接的带宽和可…...
【FreeRtos】随手记录想法和DeepSeek的交流
纯记录个人RTOS学习过程和DeepSeek的交流,或记录一些学习过程中奇怪的想法(也会喂给deepseek哈哈) 2025/3/31 1. prvCreateTask在干啥? Question prvTaskCreate这个函数做了什么:分配内存,首先会判断栈…...
【多线程】单例模式和阻塞队列
目录 一.单例模式 1. 饿汉模式 2. 懒汉模式 二.阻塞队列 1. 阻塞队列的概念 2. BlockingQueue接口 3.生产者-消费者模型 4.模拟生产者-消费者模型 一.单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,其核心思想是确保…...
Qt5.14.2+Cmake使用mingw64位编译opencv4.5成功图文教程
一、下载安装相关编译环境软件 1.1 Python3.8:安装路径:C:\Users\Administrator\AppData\Local\Programs\Python\Python38-32 安装包:python3.8.exe 1.2 QT5.14.2:安装路径:C:\Qt\Qt5.14.2 1.3 opencv4.5:解压路径D:\o…...
Transformer习题
(1) 自注意力机制的特点: 并行计算:可同时处理序列中所有位置的关联,避免RNN的时序依赖问题。长距离依赖建模:直接捕捉序列中任意两个元素的关系,不受距离限制。动态权重分配:通过查询(Query&a…...
Mamba4D阅读
CVPR 2025 创新 基于transformer的4D主干由于其二次复杂度而通常存在较大的计算成本,特别是对于长视频序列。 开发了帧内空间Mamba模块,建立时空相关性。 GPU占用和速度很有优势。 代码还没发。 Pipeline 输入点云序列,根据超参数构建点管…...
uWebSockets开发入门
一、常用C++ WebSocket开源库 一些常用的 C++ WebSocket 开源库,它们支持 WebSocket 协议的实现,适用于客户端或服务器端开发。 1. Boost.Beast (推荐) 特点:基于 Boost.Asio 的高性能库,支持 HTTP/WebSocket,属于 Boost 官方库的一部分,稳定且跨平台。 适用场景:需要高…...
x265不同preset级别控制的编码参数与编码性能影响
目录 x265中preset 实验preset效果 写在最后 x265中preset 定义:preset是x265中用于平衡编码速度与压缩效率的核心参数。通过预定义的多组编码参数组合,用户无需手动调整复杂选项即可快速选择合适的编码模式。preset控制的参数(具体参数含义解析可参考专栏中相关博客)pr…...
Qt图形化界面为何总被“冷落“?
在Qt开发者的IDE中,Qt Designer总像一个被遗忘的角落——即便它有着直观的拖拽式界面设计功能。通过分析GitHub上超过5000个Qt项目发现,仅有17%的项目使用.ui文件构建界面。这个数据背后,隐藏着开发者群体对GUI构建方式的集体选择。我们不禁要…...
手工排查后门木马的常用姿势
声明!本文章所有的工具分享仅仅只是供大家学习交流为主,切勿用于非法用途,如有任何触犯法律的行为,均与本人及团队无关!!! 1. 检查异常文件 (1)查找最近修改的文件 # 查…...
算法导论(动态规划)——简单多状态
算法思路(17.16) 状态表示: 在处理线性动态规划问题时,我们可以通过“经验 题目要求”来定义状态表示。通常有两种选择: 以某个位置为结尾的情况;以某个位置为起点的情况。 本题中,我们选择更常…...
Linux 部署 rocketmq centos7
mq部署方案 1、rocketmq 顺序消费记录 一个master ,一个 brocker ,多个group ,多个topic,采用集群消费模式。 注意 一个group 对应一个 topic。 生产者 和 消费者 可以有多个,但是 主题和分组 都是一对一的。这样保证…...
LeetCode 438. 找到字符串中所有字母的异位词
438. 找到字符串中所有字母的异位词 题目描述 给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 输入输出示例及数据范围 思路 这道题的思路其实很简单,就是一个滑动窗口的裸题&a…...
C++STL---<functional>
C标准库中的 <functional> 库是一个强大的工具集,它提供了用于处理函数对象、函数绑定、函数包装等功能的设施,极大地增强了代码的灵活性和可复用性。 1. 函数对象(Functors) 函数对象,也被称作仿函数…...
java详细笔记总结持续完善
一.Java开发环境的搭建 1. 单位换算 1TB 1024GB 1GB 1024MB 1MB 1024KB 1KB 1024Byte (字节) 1Byte 8 bit(位) 注意:一个字节占8位 2. DOS命令 DOS : Disk Operation System 磁盘操作系统 即用于操作本地磁盘的系统 命令操作符号盘符切换命令盘符名:查看当前文…...
图解AUTOSAR_SWS_CANInterface
AUTOSAR CAN接口详解文档 基于AUTOSAR标准的CAN通信接口模块架构与工作原理 目录 1. AUTOSAR CAN接口概述2. CAN接口架构 2.1 模块定位与组成2.2 内部组件结构2.3 接口关系3. CAN消息传输流程 3.1 消息发送流程3.2 消息接收流程4. CAN控制器模式管理 4.1 状态定义4.2 状态转换4…...
wsl2的centos7安装jdk17、maven
JDK安装 查询系统中的jdk rpm -qa | grep java按照查询的结果,删除对应版本 yum -y remove java-1.7.0-openjdk*检查是否删除 java -version 下载JDK17 JDK17,下载之后存到wsl目录下(看你自己)然后一键安装 sudo rpm -ivh jd…...
乐鑫ESP-Mesh-Lite方案,启明云端乐鑫代理商,创新组网拓展智能应用边界
在当今智能化浪潮的背景下,智能家居、智能农业、能源管理等领域对设备组网的需求日益增长。然而,传统的Wi-Fi组网方式常常受限于设备数量、路由器位置以及网络覆盖范围等因素,难以满足复杂场景下的多样化需求。 一方面,需要支持更…...
ISIS【路由协议讲解】-通俗易懂!
IS-IS的背景 IS-IS最初是国际标准化组织ISO为它的无连接网络协议CLNP(ConnectionLess Network Protocol)设计的一种动态路由协议。随着TCP/IP协议的流行,为了提供对IP路由的支持,IETF在相关标准中对IS-IS进行了扩充和修改…...
FastPillars:一种易于部署的基于支柱的 3D 探测器
FastPillars:一种易于部署的基于支柱的 3D 探测器Report issue for preceding element Sifan Zhou 1 , Zhi Tian 2 , Xiangxiang Chu 2 , Xinyu Zhang 2 , Bo Zhang 2 , Xiaobo Lu11{}^{1}start_FLOATSUPERSCRIPT 1 end_FLOATSUPERSCRIPT11footnotemark: 1 Chengji…...
Vitis HLS 学习笔记--块级控制(IDE 2024.1 + 执行模式 + 默认接口实现)
目录 1. 简介 2. 默认接口实现 2.1 执行模式 2.2 接口范式 2.2.1 存储器 2.2.2 串流 2.3.3 寄存器 2.3 Vitis Kernel Flow 2.3.1 默认的协议 2.3.2 vadd 代码 2.3.3 查看报告 2.4 Vivado IP Flow 2.4.1 默认的协议 2.4.2 vadd 代码 2.4.3 查看报告 3. 测试与波…...
红宝书第二十一讲:详解JavaScript的模块化(CommonJS与ES Modules)
红宝书第二十一讲:详解JavaScript的模块化(CommonJS与ES Modules) 资料取自《JavaScript高级程序设计(第5版)》。 查看总目录:红宝书学习大纲 一、模块化的意义:分而治之 模块化解决代码依赖混…...
github 页面超时解决方法
github 页面超时解决方法 每次好不容易找到github项目代码之后,满心欢喜打开却是个无法访问,心顿时又凉了半截,现在有方法可以访问github啦 快来学习 打开浏览器插件(Edge浏览器) 搜索iLink插件 并安装 打开插件 填…...
