音视频开发_SDL多线程

今天将向大家介绍一下SDL中的多线程的使用。通过下面对SDL 线程与锁相关的API介绍,你会发现,它与 Linux, Windows相关的API几乎是一模一样的。从这里可以推断出,其实SDL对于多线程的处理只是为大家提供了一套统一接口,并没有做其它太多的工作。

这是我们介绍 SDL 的第六篇文章。

为啥要用多线程?

我觉得这个小节的标题就是一个废话。不过为了文章的完整性,还是简单的说一说吧。多线程(多进程)是啥意思呢?做个不恰当的比喻,可以把CPU看成是孙悟空,它有一个能耐,从后脑揪几个猴毛就可以变出许多的小猴子。

多线程(多进程)就是这些小猴子。当干一件比较复杂的事儿时,可以孙悟空一个人干,这样自己比较累。它还有一种选择就是揪几根猴毛,让小猴子们一起帮着干。这样一件复杂的事件,分给许多猴子干,每只猴只干一部分,事情很快就被做完了,这样岂不是比一个人干要强的多?

当然,有好处也有坏外。猴子多了就需要管理,如果管理不好,就会闹翻天。比如,只有一块肉,该给哪个猴子吃呢?这真是一个另人头痛的问题。

实际上整个操作系统的演进,就是一部管理学的演进。如何才能让CPU,内存,磁盘I/O,各种设备之间高效的工作,一直是操作系统追求的目标。当然,这话有点扯远了。

今天我们要讲的就是多线程(多进程)之间该如何高效的工作。要想让多线程之间高效工作,就要给它们之间立点规矩,大家都要遵守的规矩。

线程互斥与同步

当僧多粥少时,就引入了互斥的概念。再举个我们生活中的例子吧,比如有一大家族住在同一个大屋子里,却只有一个厕所。早上起来大家都想去厕所,这时有谁先抢到了厕所,其它人就只能等他出来后再进入了,这就是互斥

当仅有一份资源,大家都需要时,这就产生了管理问题。解决的办法就是通过互斥方法来解决。这种情况是在做多线程处理时要尽量避免的;如果资源足够呢?那当然是平均分配,人人有份了。这中情况是多线路程最希望的。

除了互斥之外,有些情况还需要更精细化的管理,比如说同步。例如车间里的流水线,每个人负责一块,每一块都是半成品,第一个人完成之后交给第二个人做下一步,而后面的人又必须依赖于前而人的结果,依次类推,最后一个人才能完成最终的产品。这就是线程间的精细化管理同步

要想实现互斥和同步,就需要一种机制。在操作系统上提供了锁的概念来达到互斥与同步。

锁的种类

在操作系统上有很种锁,有读写锁、自旋锁、可重入锁等。下面我简单的介绍一下它们之间的不同。

读写锁: 分为读锁与写锁。所谓读锁就是被访问的资源只要你不改变它的值,你就可以访问,但如果你想改变它,那么就需要等所有读它的线程都释放了它们的锁后,才可以进行修改;写锁是同一时刻只能有一个人访问,当资源被加锁后,其它人只能等待。

自旋锁: 偿试着给访问资源加锁,如果此时被访问资源已经上锁了,那就一直不停的偿试,直到加锁成功为止。由于它会非常消耗CPU资源,所以一般只锁今资源非常短的情况下才能使用它。

可重入锁: 同一个线程对被访问资源可以一直加锁。但如果被访问资源已经上锁了,那么其它线程则无法对其加锁。

锁是解决互斥的一种好办法,但同样有利必有弊。如果使用不善就会出现死锁。

死锁问题

死锁顾名思意,就是打不开的锁。它是怎么产生的呢?举个例子,两个人需要一起完成一件事儿,A说他要等B做完了,他才能开始;而B说它要等A做完了,它才能开使。于时他们在相互等待中老去。

看类很简单的问题,但这类事情经常在我们的工作中出现。而在我们开发的多线程程序中更是频繁出现。别说人没遇到过哟!

如何解决?那就是考验你的管理能力了。共实很多情况是出现了死锁我们自己却不知道,否则的话,凭我们的聪名才智怎么能让他们一直锁在那儿呢。

SDL多线程

上面介绍了一大堆的理论,现在来看看 SDL 为我们都提供了那些API吧。

  • 创建线程
SDL_Thread* SDL_CreateThread(SDL_ThreadFunction fn,const char*        name,void*              data)
  • fn: 线程要运行的函数。
  • name: 线程名。
  • data: 函数参数。

等待线程

void SDL_WaitThread(SDL_Thread* thread,int*        status)
  • 等待线程结束。
  • 创建互斥量
SDL_mutex* SDL_CreateMutex(void)
  • 也就是创建一个稀有资源,这样大家就去抢这个资源。从而达到为真正资源加锁的目的。
  • 销毁互斥量
void SDL_DestroyMutex(SDL_mutex* mutex)

加锁

int SDL_LockMutex(SDL_mutex* mutex)

解锁

int SDL_UnlockMutex(SDL_mutex* mutex)

常用的与线程和锁相关的 API 就以上几个,是不是非常简单?下面我们来看一个简单的例子吧。

例子

下面这个例子是在主线程中创建了一个子线程。然后主线程就一直等待子线程结束。等子线程结束后,主线程也随之结束。

#include <stdio.h>
#include "SDL.h"/* Very simple thread - counts 0 to 9 delaying 50ms between increments */
static int TestThread(void *ptr)
{int cnt;for (cnt = 0; cnt < 10; ++cnt) {printf("\nThread counter: %d", cnt);SDL_Delay(50);}return cnt;
}int main(int argc, char *argv[])
{SDL_Thread *thread;int         threadReturnValue;printf("\nSimple SDL_CreateThread test:");/* Simply create a thread */thread = SDL_CreateThread(TestThread, "TestThread", (void *)NULL);if (NULL == thread) {printf("\nSDL_CreateThread failed: %s\n", SDL_GetError());} else {SDL_WaitThread(thread, &threadReturnValue);printf("\nThread returned value: %d", threadReturnValue);}return 0;
}

小结

本文主要介绍了两方面的内容。一是对多线程理论做了一下简单的介绍;二是介绍了SDL中与线程和锁相关的API。

最后通过一个例子显示了如何使用 SDL 中的多线程。

粉丝福利, 免费领取C++音视频学习资料包+学习路线大纲、技术视频/代码,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,编解码,推拉流,srs)↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/30360.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

汉化版PSAI全面测评,探索国产AI绘画软件的创新力量

引言 随着AI技术的飞速发展&#xff0c;图像处理和绘画领域迎来了新的变革。作为一名AIGC测评博主&#xff0c;今天我们测评的是一款国产AI绘画软件——StartAI&#xff0c;一句话总结&#xff1a;它不仅在技术上毫不逊色于国际大牌&#xff0c;更在用户体验和本地化服务上做到…

Python sorted()方法

sorted() 是Python中的一个内置函数&#xff0c;用于对可迭代对象进行排序。它返回一个新的已排序的列表&#xff0c;而不会修改原始的可迭代对象。sorted() 函数的基本语法如下&#xff1a; sorted(iterable, keyNone, reverseFalse)参数解释&#xff1a; iterable&#xff…

AI 克隆声音,只需 3 分钟(附最全教程)

作者&#xff1a;寒斜 继生成式文本大模型 Chatgpt&#xff0c;生成式图片 Stablediffusion 之后生成式语音 Text To Speech 在开源社区也出现了一匹黑马&#xff0c;就是 GPT-Sovits [ 1] 。 之所以说他是黑马&#xff0c;让人觉得惊艳&#xff0c;是因为在语音效果克隆上做…

github安全问题token和sshkeys

文章目录 sshkeys问题问题方法一:方法二:获取密钥添加密钥token问题问题:生成tokens设置tokenssshkeys问题 问题 当我们git clone代码时,会报如下错误,此时有2种解决方法。 git clone git@github.com:gjianw217/xboard-uboot.git Cloning into xboard-uboot... Permissio…

数据分析必备:一步步教你如何用matplotlib做数据可视化(6)

1、Matplotlib 网格 axes对象的grid()函数将图中网格的可见性设置为on或off。还可以显示网格的主要/次要(或两者)刻度。另外&#xff0c;可以在grid()函数中设置color&#xff0c;linestyle和linewidth属性。 参考以下示例代码 import matplotlib.pyplot as plt import numpy…

14K屏FPGA通过MIPI接口点亮

一、屏参数 屏分辨率为13320*5120&#xff0c;MIPI接口8 LANE。 二、驱动接口电路 屏偏置电压5.5V&#xff0c;逻辑供电1.8V。8 LANE MIPI&#xff0c;2 PORT。 三、MIPI DSI规范 DCS (Display Command Set)&#xff1a;DCS是一个标准化的命令集&#xff0c;用于命令模式的显…

微信公众号开发要点笔记

为了识别用户&#xff0c;每个用户针对每个公众号会产生一个安全的OpenID&#xff0c;如果需要在多公众号、移动应用之间做用户共通&#xff0c;则需前往微信开放平台&#xff0c;将这些公众号和应用绑定到一个开放平台账号下&#xff0c;绑定后&#xff0c;一个用户虽然对多个…

整理好了!2024年最常见 20 道设计模式面试题(五)

上一篇地址&#xff1a;整理好了&#xff01;2024年最常见 20 道设计模式面试题&#xff08;四&#xff09;-CSDN博客 九、什么是命令模式&#xff1f;它如何帮助实现解耦&#xff1f; 命令模式&#xff08;Command Pattern&#xff09;是一种行为设计模式&#xff0c;它将一…

奇怪的bug

奇怪的bug 合集 1.不可见字符集问题 起因是在自己做小项目的时候&#xff0c;通过lombok的data注解&#xff0c;默认生成实体类的get set方法 但是在某个方法中获取一个属性值的时候显示找不到该属性值的get方法&#xff0c;具体直接贴图 我以为是lombok的配置问题&#xff0c…

ubuntu设置静态ip地址

首先&#xff0c;查看ip地址可以使用&#xff1a; ifconfig 例如&#xff0c;出现如下结果&#xff1a; 然后&#xff0c;需要查看本地的gateway以及dns&#xff0c;可以使用&#xff1a; nmcli device show例如&#xff1a; 接下来说明一下如何设置静态ip&#xff1a;

揭秘后勤报修管理系统:目的明确,功能设计模块助您轻松管理

在数字化、信息化飞速发展的今天&#xff0c;企业后勤报修也迎来了前所未有的变革。传统的报修方式&#xff0c;如电话报修、纸质报修单等&#xff0c;已逐渐无法满足现代企事业单位对高效、便捷、精准报修服务的需求。因此&#xff0c;后勤报修管理系统应运而生&#xff0c;后…

鸣人的影分身(DP)

在火影忍者的世界里&#xff0c;令敌人捉摸不透是非常关键的。 我们的主角漩涡鸣人所拥有的一个招数——多重影分身之术——就是一个很好的例子。 影分身是由鸣人身体的查克拉能量制造的&#xff0c;使用的查克拉越多&#xff0c;制造出的影分身越强。 针对不同的作战情况&a…

C#友元函数与友元类

在C#中&#xff0c;并没有像C那样的友元函数和友元类的直接语法支持。C#中的访问控制是通过public、private、protected等访问修饰符来实现的&#xff0c;而不是通过友元的概念。 友元函数与友元类的概念 在C中&#xff0c;友元函数和友元类允许一个类或者函数访问另一个类的…

PHP转Go系列 | 变量常量的使用姿势

大家好&#xff0c;我是码农先森。 变量 在 PHP 语言中&#xff0c;初始化变量虽然只有一行&#xff0c;其实包含了两步&#xff0c;一是声明变量&#xff0c;二是赋值给变量&#xff0c;同一个变量可以任意再赋值任何类型的数据。 <?php// 初始化变量 $name "man…

Z世代职场价值观的重塑:从“班味”心态到个人成长的追求

近日&#xff0c;社交平台Soul APP联合上海市精神卫生中心&#xff08;俗称“宛平南路600号”&#xff09;发布《2024年Z世代职场心理健康报告》&#xff08;下称“报告”&#xff09;&#xff0c;发现今天的年轻人正以其独特的价值观和行为模式&#xff0c;重新定义成功与成就…

java 带有返回值的异步处理

1、先创建一个线程池 // 创建一个固定大小的线程池ExecutorService executor Executors.newFixedThreadPool(5); 2、创建一个异步现成执行你所需要执行的业务 CompletableFuture<String> future CompletableFuture.supplyAsync(() -> {System.out.println(Thread.c…

118.网络游戏逆向分析与漏洞攻防-邮件系统数据分析-邮件管理的界面与功能设计

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果&#xff0c;代码看不懂是正常的&#xff0c;只要会抄就行&#xff0c;抄着抄着就能懂了 内容…

visual studio error MSB8008:

新项目编译的时候&#xff0c;可能由于编译器的版本不一致导致的问题。 你的电脑上有两个不同版本的VS&#xff0c;或者你的程序拷贝到别人的电脑上去运行&#xff0c;或者你是从别人那里拷贝来的项目&#xff0c;而你们俩用的VS版本不一样&#xff0c;就会在运行的时候出现这…

初识Redis数据库(通俗易懂版)

Redis&#xff1a;不只是存储那么简单 Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源且高性能的键值&#xff08;key-value&#xff09;存储系统&#xff0c;同时也是内存数据库&#xff0c;常用于缓存、消息队列、会话存储等应用场景。支持字符串&#x…

MyBatis组件的DAO层拦截器

最近老大想对储存到数据库的数据进行加密&#xff0c;不让某表的某几列以明文的形式储存&#xff0c;巧的是这些数据是公司框架写好的&#xff0c;不能直接上代码改。 而业务层对于这张表的数据&#xff0c;应用的地方非常多&#xff0c;从业务侧进行拦截不现实。 所以&#xf…