嵌入式开发学习日志(linux系统编程--进程(4)——线程锁)Day30

article/2025/7/27 12:11:48

扩:typedef三种用法(简化代码编写)

一、线程的控制——互斥和同步

(一)实例引入

1、示例:

 运行结果:

 两个线程都在运行,出现问题原因:资源竞争(对全局变量都进行了读写操作)

 2、扩展:

 

 

注:reg 寄存器,暂存;alu 逻辑计算单元

(1)读数据

 

(2)计算

(3)写数据

 (二)概念

1、互斥===》在多线程中对临界资源的排他性访问。

        临界资源:公共操作的东西(可为变量、设备);

        排他性访问:多线程在同一时刻只能有一个线程进行读或写操作。

2、互斥锁===》保证临界资源的访问控制(锁在系统中本质是结构体)

     使用步骤:     定义互斥锁 ——>初始化锁 ——>加锁 ——>解锁 ——>销毁

        (1)向系统申请锁mutex(在pcb块)约定1没锁,0锁了

        (2)初始化锁

        (3)尝试使用该资源,申请到后用的时候加锁(其它线程要使用该资源尝试解

                锁,解不开锁则进入休眠等待状态)

        (4)用完后解锁释放资源,系统通知,两个线程再次同时竞争资源

        (5)不需要互斥操作后销毁锁

(三)互斥锁相关函数

1、定义锁:pthread_mutex_t mutex;

(1)pthread_mutex_t :互斥锁类型        

(2) mutex:互斥锁变量(创建在pcb块中的东西) 也称内核对象(在内核中被定义

                        的)

2、初始化锁函数:pthread_mutex_init();

形式:int pthread_mutex_init(pthread_mutex_t *restrict mutex,
                  const pthread_mutexattr_t *restrict attr);

功能:将已经定义好的互斥锁初始化。

参数:mutex 要初始化的互斥锁

                   atrr  初始化的值,一般是NULL表示默认锁

返回值:成功 0;失败 非零

3、加锁:pthread_mutex_lock();

函数原型:

        int pthread_mutex_lock(pthread_mutex_t *mutex);

功能:

                用指定的互斥锁开始加锁代码

参数: 

        mutex 用来给代码加锁的互斥锁

返回值:

                成功 0;失败 非零

  加锁后的代码到解锁部分的代码属于原子操作(汇编角度来说多个语句一把走完)
  在加锁期间其他进程/线程都不能操作该部分代码
  如果该函数在执行的时候,mutex已经被其他部分使用则代码阻塞。

4、解锁:pthread_mutex_unlock(); 

函数原型:

        int pthread_mutex_unlock(pthread_mutex_t *mutex);

功能:

        将指定的互斥锁解锁。

        解锁之后代码不再排他访问,一般加锁解锁同时出现。

参数:

        用来解锁的互斥锁

返回值:

        成功 0;失败 非零

注:解锁之后代码不再排他访问,一般加锁解锁同时出现。

5、销毁:pthread_mutex_destroy();

函数原型:

         int pthread_mutex_destroy(pthread_mutex_t *mutex);

功能:

        使用互斥锁完毕后需要销毁互斥锁

参数:

        mutex 要销毁的互斥锁

返回值:

        成功  0; 失败  非零

6、非阻塞锁:pthread_mutex_trylock();

函数原型:

        int pthread_mutex_trylock(pthread_mutex_t *mutex);

功能:

        类似加锁函数效果,唯一区别就是不阻塞(稍后再试),非阻塞锁,CPU占有率较高

参数:

        mutex 用来加锁的互斥锁

返回值:

        成功 0(操作临界资源);非0(稍后再试)

        判断返回值状态(申请成功与否),外加while(1)

适用于有多个资源的情况,一般用阻塞锁居多。

 7、注意事项

(1)上互斥锁的地方不并发;

(2)被保护的临界资源要尽可能小(不要大递归、不要sleep)

8、示例

运行结果:

 

 9、练习

 

//模拟银行取钱#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>int WIN = 3;
pthread_mutex_t mutex;void *th(void *arg) {while (1) {pthread_mutex_lock(&mutex);if (WIN > 0) {--WIN;printf("get win\n");pthread_mutex_unlock(&mutex);int ret = rand() % 5 + 1;sleep(ret);pthread_mutex_lock(&mutex);++WIN;printf("2hao我取完钱了\n");pthread_mutex_unlock(&mutex);break;} else {pthread_mutex_unlock(&mutex);}}return NULL;
}int main(int argc, char **argv) {pthread_t tid[10] = {0};int i = 0;pthread_mutex_init(&mutex, NULL);for (i = 0; i < 10; ++i) {pthread_create(&tid[i], NULL, th, NULL);}int n = 0;for (n = 0; n < 10; ++n) {pthread_join(tid[n], NULL);}pthread_mutex_destroy(&mutex);return 0;
}

 二、线程的同步

(一)概念

1、定义:有一定先后顺序的对资源的排他性访问;(同步:互斥的基础上加上顺序)

     同步原因:互斥锁可以控制排他访问但没有次序。

2、信号量(本质是结构体):锁的一种

(1)信号量的定义(申请信号量与同步线程的个数相同)

(2)初始化信号量(信号量状态初值:1该走就走;0等待)

(3)执行体操作

(4)释放的是下一个信号量

 

3、信号量的PV操作

(1)P :申请资源——申请一个二值信号量(值不是1就是0)

(2)V :释放资源——释放一个二值信号量

4、信号量的分类

(1)无名信号量 ——>线程间通信

(2)有名信号量 ——>进程间通信

5、框架

        信号量的定义==》信号量的初始化==》信号量的pv操作==》信号量的销毁

(二)信号量相关函数

1、定义信号量:sem_t sem;

  sem_t                    sem;
   信号量的类型     信号量的变量

2、初始化信号量:sem_init();

函数原型:int sem_init(sem_t *sem, int pshared, unsigned int value);

功能:将已经定义好的信号量赋值;

参数:sem 要初始化的信号量

           pshared = 0 (表示线程间使用信号量);

           pshared != 0 (表示进程间使用信号量);

           value 信号量的初始值,一般无名信号量都是二值信号量(0 1) :

                       0 表示红灯,进程暂停阻塞;

                       1 表示绿灯,进程可以通过执行;

返回值:成功  0;失败  -1

3、申请信号量(P操作):sem_wait();

(1)函数原型int sem_wait(sem_t *sem);

(2)功能:判断当前sem信号量是否有资源可用。

                    如果sem有资源(==1),则申请该资源,程序继续运行;

                     如果sem没有资源(==0),则线程阻塞等待,一旦有资源则自动申请资源并

                        继续运行程序。

        :sem申请资源后会自动执行sem=sem-1;

(3)参数:sem 要判断的信号量资源;

(4)返回值:成功 0 ;失败 -1

4、释放信号量(V操作):sem_post();

(1)函数原型:int sem_post(sem_t *sem);

(2)功能:函数可以将指定的sem信号量资源释放;

                    并默认执行,sem = sem+1;

                    线程在该函数上不会阻塞。

(3)参数:sem 要释放资源的信号量;

(4)返回值:成功 0;失败 -1

5、销毁:sem_destroy();

(1)函数原型: int sem_destroy(sem_t *sem);

(2)功能:使用完毕将指定的信号量销毁;

(3)参数:sem要销毁的信号量;

(4)返回值:成功 0;失败  -1

6、信号量的两种用法示例

(1)同步(互斥+顺序):二值信号量

 

 

(2)互斥:计数信号量

资源个数不是1个时可使用

 

 三、死锁

1、死锁定义

        死锁是指多个进程或线程在竞争资源时,由于互相等待对方释放资源而陷入无限阻

塞的状态。(归根结底是逻辑错误导致的)

2、产生死锁的原因

(1) 因为系统资源不足。

(2) 进程运行推进的顺序不合适。

(3) 资源分配不当等。

如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。

 3、产生死锁的四个必要条件(面问)

(1) 互斥条件:一个资源每次只能被一个进程或线程使用。(若死锁可先把阻塞锁换

                                成非阻塞锁找出错误后改回)

(2) 请求与保持条件:一个进程或线程因请求资源而阻塞时,对已获得的资源保持不

                                        放。

(3) 不剥夺条件:进或线程程已获得的资源,在末使用完之前,不能强行剥夺。

(4) 循环等待条件:若干进程或线程之间形成一种头尾相接的循环等待资源关系。


http://www.hkcw.cn/article/ncZSRaywQX.shtml

相关文章

从图像处理到深度学习:直播美颜SDK的人脸美型算法详解

在直播的镜头前&#xff0c;每一位主播都希望自己“光彩照人”。但在高清摄像头无死角的审视下&#xff0c;哪怕是天生丽质&#xff0c;也难免需要一点技术加持。于是&#xff0c;美颜SDK应运而生&#xff0c;成为直播平台提升用户粘性和视觉体验的重要工具。 尤其是在“人脸美…

编译rustdesk,使用flutter、hwcodec硬件编解码

目录 安装相应的环境安装visual studio安装vpkg安装rust开发环境安装llvm和clang编译源码下载源码使用Sciter作为UI的(已弃用)使用flutter作为UI的(主流)下载flutter sdk桥接静默安装最近某desk免费的限制越来越多,实在没办法,平时远程控制用的比较多,只能用rustdesk了,…

Dynamics 365 Business Central EC Sales List 欧洲共同体 (EC) 销售列表

什么是EC Sales List? 是在欧盟境内 开立的具有增值税主体公司的一项报告义务&#xff0c;提供欧盟国家/地区企业之间的跨境交易记录。ESL 的目的是确保这些交易中的所有相关方都支付和申报了适当金额的增值税。 随着出海企业越来越多的在欧州开展业务&#xff0c;此项报告需…

将图片存为二进制流到数据库并展示到前端的实现

使用图片直接存储到数据库中可能会出现以下问题&#xff1a; 1.图片的存储太多了占用数据库的存储空间 2.图片占用内存较大在传输和渲染的情况下会影响应用性能 3.一般情况下是将图片上传云服务器然后数据库存地址&#xff0c;这里讲解的情况只适合图片较少的情景 这里使用…

pikachu通关教程-RCE

目录 RCE(remote command/code execute)概述: exec "ping" 管道符 乱码问题 RCE(remote command/code execute)概述: RCE漏洞&#xff0c;可以让攻击者直接向后台服务器远程注入操作系统命令或者代码&#xff0c;从而控制后台系统 分为远程代码和远程命令两种.当…

合合信息首批通过中国信通院文档图像篡改检测平台能力完备性测评

随着 AIGC 技术的迅速发展&#xff0c;图像篡改手段日益多样化和隐蔽化&#xff0c;给各行业带来了严峻挑战。虚假证照、伪造合同等文档不仅威胁企业的运营安全&#xff0c;也对社会诚信体系构成冲击。在中国信通院最新开展的文档图像篡改检测平台能力完备性测评中&#xff0c;…

线程池的详细知识(含有工厂模式)

前言 下午学习了线程池的知识。重点探究了ThreadPoolExecutor里面的各种参数的含义。我详细了解了这部分的知识。其中有一个参数涉及工厂模式&#xff0c;我将这一部分知识分享给大家~ 线程池的详细介绍(含工厂模式) 结语 分享到此结束啦。byebye~

力扣HOT100之动态规划:279. 完全平方数

这道题之前在刷代码随想录的时候做过&#xff0c;但是现在给忘干净了&#xff0c;现在甚至都不记得这是一个背包问题。。。又反过头去看代码随想录的视频才做出来的。这道题就是一个背包问题&#xff0c;这个问题可以抽象为&#xff1a;对于容量为j的背包&#xff0c;要计算出恰…

Pytorch Geometric官方例程pytorch_geometric/examples/link_pred.py环境安装教程及图数据集制作

最近需要训练图卷积神经网络&#xff08;Graph Convolution Neural Network, GCNN&#xff09;&#xff0c;在配置GCNN环境上总结了一些经验。 我觉得对于初学者而言&#xff0c;图神经网络的训练会有2个难点&#xff1a; ①环境配置 ②数据集制作 一、环境配置 我最初光想…

AI预测3D新模型百十个定位预测+胆码预测+去和尾2025年5月30日第93弹

从今天开始&#xff0c;咱们还是暂时基于旧的模型进行预测&#xff0c;好了&#xff0c;废话不多说&#xff0c;按照老办法&#xff0c;重点8-9码定位&#xff0c;配合三胆下1或下2&#xff0c;杀1-2个和尾&#xff0c;再杀4-5个和值&#xff0c;可以做到100-300注左右。 (1)定…

架构加速-深度学习教程

由于RK、jetson nano和电脑的GPU不相同&#xff0c;对应的pytorch也不同&#xff0c;因此不能直接将电脑训练好的模型丢到板端运行&#xff0c;因为训练的模型框架不同。就像你torch1.13和torch2.0都不一定支持&#xff0c;更何况不同平台上的torch。因此需要进行onnx模型转化&…

顶会新热门:机器学习可解释性

&#x1f9c0;机器学习模型的可解释性一直是研究的热点和挑战之一&#xff0c;同样也是近两年各大顶会的投稿热门。 &#x1f9c0;这是因为模型的决策过程不仅需要高准确性&#xff0c;还需要能被我们理解&#xff0c;不然我们很难将它迁移到其它的问题中&#xff0c;也很难进…

MicroPython+L298N+ESP32控制电机转速

要使用MicroPython控制L298N电机驱动板来控制电机的转速&#xff0c;你可以通过PWM&#xff08;脉冲宽度调制&#xff09;信号来调节电机速度。L298N是一个双H桥驱动器&#xff0c;可以同时控制两个电机的正反转和速度。 硬件准备&#xff1a; 1. L298N 电机控制板 2. ESP32…

Chainlink:连接 Web2 与 Web3 的去中心化桥梁

区块链技术通过智能合约实现了去中心化的自动执行&#xff0c;但智能合约无法直接访问链下数据&#xff0c;限制了其在现实世界的应用。Chainlink 作为去中心化预言机网络&#xff0c;以信任最小化的方式解决了这一问题&#xff0c;成为连接传统互联网&#xff08;Web2&#xf…

杨传辉:构建 Data × AI 能力,打造 AI 时代的一体化数据底座|OceanBase 开发者大会实录

5 月 17 日&#xff0c;OceanBase 在广州举办第三届开发者大会。主论坛环节&#xff0c;OceanBase CTO 杨传辉系统阐述了 Data AI 战略&#xff0c;并正式推出三大产品&#xff1a;PowerRAG、共享存储 及OceanBase桌面版。 杨传辉指出&#xff0c;数据与AI模型的一体化融合&a…

AU6825集成音频DSP的2x32W数字型ClaSSD音频功率放大器(替代TAS5825)

1.特性 ● 输出配置 - 立体声 2.0: 2 x 32W (8Ω,24V,THD N 10%) - 立体声 2.0: 2 x 26W (8Ω,21V,THD N 1%) ● 供电电压范围 - PVDD:4.5V -26.4V - DVDD: 1.8V 或者 3.3V ● 静态功耗 - 37mA at PVDD12V ● 音频性能指标 - THDN ≤ 0.02% at 1W,1kHz - SNR ≥ 107dB (A-wei…

关于ADS分辨率问题

笔记本上使用ADS&#xff08;Advanced Design System &#xff09;默认的界面挺大的&#xff0c;图标和字体都大&#xff0c;界面清新&#xff0c;给人一种呆呆易上手的感觉。 整个屏幕的截图 直到我打开了这个OPTIM的选项卡&#xff0c;它太长了&#xff0c;由于缩放太大&am…

海外DeepLink方案复杂?用openinstall一站式链接世界

App出海难免水土不服&#xff0c;商业模型、用户画像、增长方向没有一样是省心的&#xff0c;国内标配的DeepLink&#xff08;深度链接&#xff09;方案如果照搬出海同样无法达到最佳体验。 要知道国内外移动端生态是截然不同的&#xff0c;除了主流的URL Scheme和iOS Univers…

Ollama(1)知识点配置篇

ollama已经成功安装成功后&#xff0c;通常大家会对模型的下载位置和访问权限进行配置 1.模型下载位置修改 都是修改系统环境变量。 &#xff08;1&#xff09;默认下载位置 macOS: ~/.ollama/modelsLinux: /usr/share/ollama/.ollama/modelsWindows: C:\Users\你的电脑用户…

C# SolidWorks二次开发-实战1,找文件名不同实体相同的零件。

今天这篇文章话题来源于群里的聊天&#xff0c;在讨论有些插件功能的开发原理。 如标题&#xff0c;今天讲的是如何查找零件文件名不一样&#xff0c;但实际可能是同一个东西的办法。 - 题外话 熟悉Solidworks的人都知道&#xff0c;Solidworks有一个比较零件或者特征不同点的…