29_SDL多线程与锁机制
一、简介
为什么要用多线程?在音视频领域主要是实现音视频同步。实现了音视频同步,我们的播放器就基本上合格了。
多线程的好处主要是能使程序更加充分利用硬件(主要是CPU)的性能。但是也存在相应的隐患,如果多线程管理不好,会出现协调问题。
这里我们将讲解一下SDL的多线程与锁机制。
引进的机制:线程的互斥与同步
- 互斥:同一个资源在一定时间内只能由一个方法访问。
- 同步:一个方法完成后的内容需要同步到其他的方法,在由其他方法操作完成后的内容。
- 锁与信号量
- 锁用于完成互斥;信号量用于同步。
- 锁的种类:读写锁、自旋锁、可重入锁。
SDL线程创建:SDL_CreateThread
SDL线程等待:SDL_WaitThead
SDL互斥锁:SDL_CreateMutex / SDL_DestroyMutex
SDL锁定互斥:SDL_LockMutex / SDL_UnlockMutex
SDL 条件变量(信号量):SDL_CreateCond / SDL_DestoryCond
SDL 条件变量(信号量)等待 / 通知 :SDL_CondWait / SDL_CondSingal
二、代码实现:
我们通过SDL的锁机制实现生产者和消费者
2.1、声明
//mainwindow.h
Ui::MainWindow *ui;
/** 互斥锁*/
SDL_mutex *_mutex = nullptr;
/** 条件变量:消费者等待,生产者唤醒 */
SDL_cond *_cond = nullptr;
std::list<QString> *_list = nullptr;
int _index = 0;
void consume(QString name);
void produce(QString name);
2.2、创建锁、消费者
//mainwindow.cpp
// 创建互斥锁
_mutex = SDL_CreateMutex();
// 创建条件变量
_cond = SDL_CreateCond();
// 创建链表
_list = new std::list<QString>();
// 创建消费者
consume("消费者1");
consume("消费者2");
consume("消费者3");
consume("消费者4");
2.3、销毁
MainWindow::~MainWindow(){
delete ui;
delete _list;
SDL_DestroyMutex(_mutex);
SDL_DestroyCond(_cond);
}
2.4、实现生产者逻辑
void MainWindow::produce(QString name){
std::thread([this,name](){
SDL_LockMutex(_mutex);
qDebug() << name << "开始生产";
_list->push_back(QString("%1").arg(++_index));
_list->push_back(QString("%1").arg(++_index));
_list->push_back(QString("%1").arg(++_index));
// 唤醒消费者:赶紧开始消费
SDL_CondSignal(_cond);
SDL_UnlockMutex(_mutex);
}).detach();
}
2.5、实现销毁者逻辑
void MainWindow::consume(QString name){
std::thread([this,name](){
SDL_LockMutex(_mutex);
while (true) {
qDebug() << name << "开始消费";
while (!_list->empty()) {
qDebug() << _list->front();
// 删除头部
_list->pop_front();
// 睡眠500ms
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
/**
* 1.释放互斥锁
* 2.等待条件_cond
* 3.等到了条件_cond、加锁
*/
SDL_CondWait(_cond,_mutex);
}
SDL_UnlockMutex(_mutex);
}).detach();
}
2.6、创建生产者
void MainWindow::on_produceBtn_clicked(){
// 创建生产者
produce("生产者1");
produce("生产者2");
produce("生产者3");
}
三、分装SDL锁机制
我们可以将SDL的锁机制的api进行二度分装,以便后面的音视频使用
condmutex.h
#ifndef CONDMUTEX_H
#define CONDMUTEX_H
#include <SDL2/SDL.h>
class CondMutex {
public:
CondMutex();
~CondMutex();
void lock();
void unlock();
void signal();
void broadcast();
void wait();
private:
/** 互斥锁 */
SDL_mutex *_mutex = nullptr;
/** 条件变量 */
SDL_cond *_cond = nullptr;
};
#endif // CONDMUTEX_H
condmutex.cpp
#include "condmutex.h"
CondMutex::CondMutex(){
// 创建互斥锁
_mutex = SDL_CreateMutex();
// 创建条件变量
_cond = SDL_CreateCond();
}
CondMutex::~CondMutex(){
SDL_DestroyMutex(_mutex);
SDL_DestroyCond(_cond);
}
void CondMutex::lock(){
SDL_LockMutex(_mutex);
}
void CondMutex::unlock(){
SDL_UnlockMutex(_mutex);
}
void CondMutex::signal(){
SDL_CondSignal(_cond);
}
void CondMutex::broadcast(){
SDL_CondBroadcast(_cond);
}
void CondMutex::wait(){
SDL_CondWait(_cond,_mutex);
}
29_SDL多线程与锁机制的更多相关文章
- SDL 开发实战(七): SDL 多线程与锁机制
为什么要用多线程?在音视频领域主要是实现音视频同步.实现了音视频同步,我们的播放器就基本上合格了. 这里我们将讲解一下SDL的多线程与锁机制. 多线程的好处主要是能使程序更加充分利用硬件(主要是CPU ...
- C 语言多线程与锁机制
C 语言多线程与锁机制 多线程 #include <pthread.h> void *TrainModelThread(void *id) { ... pthread_exit(NULL) ...
- JAVA多线程与锁机制
JAVA多线程与锁机制 1 关于Synchronized和lock synchronized是Java的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码 ...
- Java多线程(二) 多线程的锁机制
当两条线程同时访问一个类的时候,可能会带来一些问题.并发线程重入可能会带来内存泄漏.程序不可控等等.不管是线程间的通讯还是线程共享数据都需要使用Java的锁机制控制并发代码产生的问题.本篇总结主要著名 ...
- java多线程(三)——锁机制synchronized(同步语句块)
用关键字synchronized声明方法在某些情况下是有弊端的,比如A线程调用同步方法之行一个长时间的任务,那么B线程必须等待比较长的时间,在这样的情况下可以使用synchronized同步语句快来解 ...
- java多线程(二)——锁机制synchronized(同步方法)
synchronized Java语言的关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码.当两个并发线程访问同一个对象object中 ...
- Lucene的多线程访问原则和同步,锁机制
本文介绍lucene多线程环境下的使用原则和commit.lock与write.lock实现的锁机制. 设计之初就是服务于多线程环境,大多数情况下索引会被不至一个线程访问.索引时一个关键资源.在对这样 ...
- [java多线程] - 锁机制&同步代码块&信号量
在美眉图片下载demo中,我们可以看到多个线程在公用一些变量,这个时候难免会发生冲突.冲突并不可怕,可怕的是当多线程的情况下,你没法控制冲突.按照我的理解在java中实现同步的方式分为三种,分别是:同 ...
- Java CAS同步机制 原理详解(为什么并发环境下的COUNT自增操作不安全): Atomic原子类底层用的不是传统意义的锁机制,而是无锁化的CAS机制,通过CAS机制保证多线程修改一个数值的安全性。
精彩理解: https://www.jianshu.com/p/21be831e851e ; https://blog.csdn.net/heyutao007/article/details/19 ...
- Java多线程5:Synchronized锁机制
一.前言 在多线程中,有时会出现多个线程对同一个对象的变量进行并发访问的情形,如果不做正确的同步处理,那么产生的后果就是“脏读”,也就是获取到的数据其实是被修改过的. 二.引入Synchronized ...
随机推荐
- java判断系统时间是否在规定的时间区间之内
java判断系统时间是否在规定的时间区间之内 1️⃣ 创建controller => service => serviceimpl package com.preciouslove.xin ...
- AOF
AOF 基础概念 以日志的形式记录了每个写操作 在redis重新运行时,会将这些操作重新执行一遍 文件形式:appendonly.aof 开启AOF需要更改配置文件:appendonly:yes AO ...
- Redis的Java客户端-Jedis
Redis的Java客户端-Jedis 在Redis官网中提供了各种语言的客户端,地址:https://redis.io/docs/clients/ 其中Java客户端也包含很多: 标记为的就是推荐使 ...
- 内存泄漏定位工具之 mtrace(二)
1 前言 mtrace(memory trace),是 GNU Glibc 自带的内存问题检测工具,它可以用来协助定位内存泄露问题.它的实现源码在glibc源码的malloc目录下,其基本设计原理为设 ...
- NEMU PA 1 实验报告
课程地址: PA1-1 https://www.bilibili.com/video/BV1JE411J7AK PA1-2 https://www.bilibili.com/video/BV1EE41 ...
- 源码剖析Spring依赖注入:今天你还不会,你就输了
在之前的讲解中,我乐意将源码拿出来并粘贴在文章中,让大家看一下.然而,我最近意识到这样做不仅会占用很多篇幅,而且实际作用很小,因为大部分人不会花太多时间去阅读源码. 因此,从今天开始,我将采取以下几个 ...
- LLaMA 2 - 你所需要的一切资源
摘录 关于 LLaMA 2 的全部资源,如何去测试.训练并部署它. LLaMA 2 是一个由 Meta 开发的大型语言模型,是 LLaMA 1 的继任者.LLaMA 2 可通过 AWS.Hugging ...
- 使用UTL_HTTP包获取网页内容
UTL_HTTP 包提供了容易的方式通过HTTP协议获取网页内容,下面结合几个例子介绍一下: ----------------------------------------------------- ...
- Java String类的replaceAll方法
代码勇士真题: 给定一个字符串由a-z字母组成的字符串s,长度任意字母可任意组合. 要求编写函数找出s中不在a-m范围内的字母个数n,要求函数返回字符串格式为:n/s的长度 例如: s="a ...
- 使用@ControllerAdvice统一处理自定义异常
最近工作中涉及到捕捉AOP方法中抛出的异常. 想针对某一种异常做一个统一的处理器并封装好异常信息以JSON格式交给前端进行提示. 主要实现的话有以下几步: 1.编写自定义异常类 package com ...