OpenHarmony智能开发套件—内核编程(下)
想了解更多关于开源的内容,请访问:
51CTO开源基础软件社区
https://ost.51cto.com
前言
本篇基于上一篇OpenHarmony智能开发套件[内核编程·上]继续介绍OpenHarmony在智能开发套件Hi3861上的内核编程学习。
内核编程
还不了解OpenHarmony内核的伙伴们可以参考上篇文章,上篇已经简单通俗地介绍了OpenHarmony的内核。
OpenHarmony智能开发套件内核编程·上
互斥锁
线程的状态
在介绍互斥锁之前,我们有必要去了解一下线程的状态,或者说线程的生命周期。避免伙伴们因为不够熟悉线程而对这个互斥锁的概念感到困难。
首先介绍一下线程的几个状态,他们分别有:
创建创建线程,在OpenHarmony的源码中,线程的属性被封装成了一个名为”osThreadAttr_t“的结构体
typedef struct {const char *name;uint32_t attr_bits;void *cb_mem;uint32_t cb_size;void *stack_mem;uint32_t stack_size;osPriority_t priority;TZ_ModuleId_t tz_module;uint32_t reserved;} osThreadAttr_t;name:线程的名称。attr_bits:线程属性位。cb_mem:线程控制块的内存地址。cb_size:线程控制块的内存大小。stack_mem:线程栈的内存地址。stack_size:线程栈的大小。priority:线程的优先级。tz_module:线程所属的TrustZone模块。reserved:保留字段。当我们创建一个线程的时候,系统就会为该线程分配所需要的资源,将线程加入到系统的线程调度队列中,此时线程已经处在就绪状态了。
就绪线程一旦被创建,就会进入就绪状态,他表示我们完成的线程的创建(线程相关属性的初始化),但是并未运行,线程正在等待操作系统调度程序,将其调度运行起来。
运行在上篇我们介绍了一个关于线程的API,他可以将就绪状态的线程加入到活跃线程组
osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr);此时的线程将会占用部分cpu资源执行他的程序,直到程序结束,或者线程被阻塞,cpu被抢占等。
阻塞线程阻塞,可以理解为线程无法继续往下执行,但时线程执行的程序不会直接退出,他会进入到等待的状态,直到相关资源被释放,线程可以继续执行。
终止上篇我们介绍了线程终止的API
sStatus_t status = osThreadTerminate(osThreadId_t tid);此时线程完成了自己的代码逻辑,我们方可主动调用该API彻底删除这个线程。
当然如果具体细分,其实不止这五个状态,但是了解了这五个状态就足够了。下面我们来聊聊什么是互斥锁。
互斥锁简介
互斥锁的应用场景时处理多线程,资源访问的问题。这里还是给大家举一个例子:动物园卖票。
在我们的程序设计中,往往会有共有资源,每个线程都可以进来访问这些资源。这里的共有资源就是我们的门票,一个售票口就是一个线程,当有人来窗口买票,我们的门票就会减少一张。当然一个动物园的流量时巨大的,我们不能只设立一个售票口,这样的效率是很低的。京东淘宝抢购秒杀也一样,我们必须设立多个窗口,在同一时刻为多个人处理业务。多线程解决了效率问题但也带来了安全隐患。
我们假设一个这样的场景,动物园仅剩一张门票,但是有两个在不同的窗口同时付了钱,当售票员为他们拿票的时候就会发现,少了一张票,两个人都付了钱都想要那张票,就陷入了一个死局,无奈动物园只能让他们都进去。但是在程序中体现的可能就是一个bug,动物园的门票剩余数为:-1。
if(count >0){count--;}售票的逻辑很简单,只要票数大于零,还有票能卖,那就在此基础上减掉一。问题就在于,两个线程同时在count = 1的时候通过了if判断,都执行的count–;那么就会出现了count = -1,也就是票数为负 的bug结果。
互斥锁的出现就很好地解决了一个问题,他能够阻止上面两个线程同时访问资源的同步行为,也就是说当一个线程进入这个if语句后,别的线程都不能进入。形象起来说,就像对这段代码加了锁,只有有钥匙的线程才能够访问它。
互斥锁API
通过对几个API的介绍,让大家知道怎么为一段代码加上互斥锁
创建互斥锁。与线程的定义一样,互斥锁也封装成了一个结构体
typedef struct {/** Mutex name */const char *name;/** Reserved attribute bits */uint32_t attr_bits;/** Memory for the mutex control block */void*cb_mem;/** Size of the memory for the mutex control block */uint32_t cb_size;} osMutexAttr_t;name:互斥锁的名称attr_bits:保留的属性位cb_mem:互斥锁控制块的内存cb_size:互斥锁控制块内存的大小获取互斥锁的id。osMutexId_t osMutexNew(const osMutexAttr_t *attr);将我们上面定义的互斥锁属性传入函数,返回互斥锁的id
线程获取互斥锁osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout);传入互斥锁id,设置我们的延迟时间,当线程获取到我们的互斥锁时,返回的状态是osOK。
下面是全部的状态码。
typedef enum {/** Operation completed successfully */osOK=0,/** Unspecified error */osError = -1,/** Timeout */osErrorTimeout= -2,/** Resource error */osErrorResource = -3,/** Incorrect parameter */osErrorParameter= -4,/** Insufficient memory */osErrorNoMemory = -5,/** Service interruption */osErrorISR= -6,/** Reserved. It is used to prevent the compiler from optimizing enumerations. */osStatusReserved= 0x7FFFFFFF} osStatus_t;释放锁。osStatus_t osMutexRelease(osMutexId_t mutex_id);当我们的线程执行完业务后需要把锁释放出来,让别的线程获取锁,执行业务。当然这个过程是线程之间的竞争,一个线程可能一直得不到锁,一个线程也可能刚释放锁又获得锁,我们可以添加休眠操作,提高锁在各个线程间的分配。
其他API请参考:
Mutex API
操作
新建样例目录。applications/sample/wifi-iot/app/mutex_demo新建源文件和gn文件。applications/sample/wifi-iot/app/mutex_demo/mutex.capplications/sample/wifi-iot/app/mutex_demo/BUILD.gn源码编写。因为已经介绍了主要的API,这里就直接给伙伴们上源码了。
#include结果展示
可能有的伙伴们看到这里不太清晰,会觉得这段代码真的上锁了吗?
if(osMutexAcquire(*mid, 100) == osOK){if(count > 0){count--;printf("[Mutex Test] Thread %s get a value, the less is %d.\r\n", osThreadGetName(osThreadGetId()), count);} else {printf("[Mutex Test] The value is out!\r\n");osThreadTerminate(osThreadGetId());}}那么我们可以不使用互斥锁再次执行这段代码。
结果展示如下:
注:这里笔者还另外多加了3个线程,一共六个线程,可以看出来控制台的输出很混乱,当一个线程在执行输出指令时,另一个线程也插了进来执行输出指令所造成的,再看票数,也是出现了明显的问题。因此互斥锁在处理多线程问题时,起到了非常重要的作用。
可能有伙伴好奇,怎么没有负数票的出现,笔者作为学习者,代码能力也有限,可能写出来的案例并不是非常精确,仅供参考。
信号量
对大部分初学者而言,这又是一个新名词,什么是信号量?其实他跟我们上篇介绍的互斥锁很像。互斥锁是在多线程中允许一个线程访问资源,信号量是在多线程中允许多个线程访问资源。
初学者一定会感到困惑,为了解决多线程访问资源的风险我们限制只能有一个线程在某一时刻访问资源,现在这个信号量怎么有允许多个线程访问资源呢。笔者刚开始也比较困惑,结合一些案例理解后,也是明白了这样的设计初衷。实际上,信号量,互斥锁本就是两种不同的多形成同步运行机制,在特定的应用场景下,有特定的需求,而信号量,互斥锁可以满足不同的需求,具体是什么需求呢,举个例子给大家。
卖票,我们的确需要互斥锁解决多线程可能带来的错误,那么如果是验票呢,为了提高效率,我们开设多个入口同时验票且不会发生冲突,信号量就做到了限制线程数量访问资源的作用。如果我们不限制并发的数量,我们的程序占用资源可能会非常大,甚至崩溃,就像检票的入口没有被明确入口数量一样,门口的人们会乱成一片。
信号量API
创建信号量。osSemaphoreId_t osSemaphoreNew(uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr);参数解释:最大容量量,初始容纳量,信号量属性。
最大容纳量说明了,我们的资源最大能被多少线程访问。
初始容纳量说明了,我们当前实际能有多少线程访问资源,因为一个信号对应一个线程的许可。
返回值:信号量的id。
获取信号量。osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id, uint32_t timeout);参数解释:信号量的id,等待时长。
返回值:状态码 (介绍很多遍了,就不说明了)。
我们往往会在timoeout处设置为 oswaitForever。
#define osWaitForever 0xFFFFFFFFU这样我们的线程就会一直等,直到有信号量空出来被他获取,才执行后续的代码。
释放信号量。osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id);很简单,传入信号量的id,就可以释放一个信号量出来。
其他的API请参考:
Semaphore API
任务
有4个售票窗,2个检票口,每次会有4个人来买票,然后去检票,用互斥锁控制购票,信号量控制检票。
操作
新建样例目录。applications/sample/wifi-iot/app/semaphore_demo。新建源文件和gn文件。applications/sample/wifi-iot/app/semaphore_demo/semaphore.c。applications/sample/wifi-iot/app/semaphore_demo/BUILD.gn。源码编写。直接上源码了。
#include结果展示
大家可以加长检票业务的休眠时间,我们的检票口是两个,in的业务一定是两个一起执行的。
总之信号量和互斥锁是多线程管理中的重点,大家一定要好好体会他们的作用和区别。
消息队列
本篇的最后我们来介绍消息队列。队列相信大部分朋友都不陌生,是一种基本且常用的数据结构,这里笔者就不介绍队列的相关信息了。那么什么是消息队列呢?有什么应用场景呢。
消息队列也是多线程,高并发中的处理方式,大家可以理解为“同步入队,异步出队”。老样子从一个案例解释,网购秒杀。
在网购秒杀时,会有上万甚至上百万的流量涌入服务器,下单即可看作一个请求,向服务器请求获取某个商品。服务器处理,生成买家的订单号。当然强大服务器的也无法在同一时刻支持如此多的请求,并且商品的数量也不足被所有人购买,这个时候,我们的消息队列就会同步接受大家的请求,所有的请求都会被压进一个队列中,服务器从队列中依次获取消息,确保不会因为资源被占用而导致系统崩溃。
#### 消息队列API创建消息队列。osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr);参数说明:
msg_count:消息队列中的消息数量。msg_size:消息队列中每个消息的大小,通常我们的消息会用一个结构体来自定义消息的内容attr:指向消息队列属性。该函数的返回值是osMessageQueueId_t类型,表示消息队列的ID。如果创建消息队列失败,函数将返回NULL。
向消息队列加入消息。osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout);参数说明:
mq_id:消息队列的ID,通过调用osMessageQueueNew函数获得。msg_ptr:指向要放入消息队列的消息缓冲区的指针,也就是我们将结构体的指针转递给函数msg_prio:消息的优先级。timeout:延时,使用osWaitForever,线程就会一直等待直到队列中有空余的位置。该函数的返回值是osStatus_t类型,表示函数执行的结果。
从消息队列中接受消息。osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout);参数说明:
mq_id:消息队列的ID,通过调用osMessageQueueNew函数获得。msg_ptr:指向存储从消息队列中获取的消息的缓冲区的指针。msg_prio:指向存储从消息队列中获取的消息的优先级的缓冲区的指针。timeout:延时,使用osWaitForever,线程就会一直等待直到队列中有消息了。该函数的返回值是osStatus_t类型,表示函数执行的结果。
删除消息队列。osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id);参数说明:
mq_id:消息队列的ID,通过调用osMessageQueueNew函数获得。该函数的返回值是osStatus_t类型,表示函数执行的结果。
其他的API请参考:
MessageQueue API
任务
模拟抢购秒杀,假设我们有10个线程,15个大小的消息队列,5件商品。
操作
新建样例目录。applications/sample/wifi-iot/app/queue_demo。新建源文件和gn文件。applications/sample/wifi-iot/app/queue_demo/queue.c。applications/sample/wifi-iot/app/queue_demo/BUILD.gn。编写源码。直接上源码。
#include结果展示
因为线程创建是循环创建的,先创建的线程就优先发送了请求,可以看的出来,前五个线程抢到了商品。如果线程可以同时发送请求,争抢入队的时机,模拟将会更加准确一些,这里只是简单的模拟。
结束语
至此内核的基础内容就给伙伴们介绍完了,内核作为一个系统的底层起到了相当重要的作用,大家要好好体会,希望能帮助到学习OpenHarmony的伙伴们。
想了解更多关于开源的内容,请访问:
51CTO开源基础软件社区
https://ost.51cto.com
推荐系统
电脑公司Ghost Win8.1 x32 精选纯净版2022年7月(免激活) ISO镜像高速下载
语言:中文版系统大小:2.98GB系统类型:Win8电脑公司Ghost Win8.1x32位纯净版V2022年7月版本集成了自2022流行的各种硬件驱动,首次进入系统即全部硬件已安装完毕。电脑公司Ghost Win8.1x32位纯净版具有更安全、更稳定、更人性化等特点。集成最常用的装机软件,精心挑选的系统维护工具,加上绿茶独有
微软Win11原版22H2下载_Win11GHOST 免 激活密钥 22H2正式版64位免费下载
语言:中文版系统大小:5.13GB系统类型:Win11微软Win11原版22H2下载_Win11GHOST 免 激活密钥 22H2正式版64位免费下载系统在家用办公上跑分表现都是非常优秀,完美的兼容各种硬件和软件,运行环境安全可靠稳定。Win11 64位 Office办公版(免费)优化 1、保留 Edge浏览器。 2、隐藏“操作中心”托盘图标。 3、保留常用组件(微软商店,计算器,图片查看器等)。 5、关闭天气资讯。
Win11 21H2 官方正式版下载_Win11 21H2最新系统免激活下载
语言:中文版系统大小:4.75GB系统类型:Win11Ghost Win11 21H2是微软在系统方面技术积累雄厚深耕多年,Ghost Win11 21H2系统在家用办公上跑分表现都是非常优秀,完美的兼容各种硬件和软件,运行环境安全可靠稳定。Ghost Win11 21H2是微软最新发布的KB5019961补丁升级而来的最新版的21H2系统,以Windows 11 21H2 22000 1219 专业版为基础进行优化,保持原汁原味,系统流畅稳定,保留常用组件
windows11中文版镜像 微软win11正式版简体中文GHOST ISO镜像64位系统下载
语言:中文版系统大小:5.31GB系统类型:Win11windows11中文版镜像 微软win11正式版简体中文GHOST ISO镜像64位系统下载,微软win11发布快大半年了,其中做了很多次补丁和修复一些BUG,比之前的版本有一些功能上的调整,目前已经升级到最新版本的镜像系统,并且优化了自动激活,永久使用。windows11中文版镜像国内镜像下载地址微软windows11正式版镜像 介绍:1、对函数算法进行了一定程度的简化和优化
微软windows11正式版GHOST ISO镜像 win11下载 国内最新版渠道下载
语言:中文版系统大小:5.31GB系统类型:Win11微软windows11正式版GHOST ISO镜像 win11下载 国内最新版渠道下载,微软2022年正式推出了win11系统,很多人迫不及待的要体验,本站提供了最新版的微软Windows11正式版系统下载,微软windows11正式版镜像 是一款功能超级强大的装机系统,是微软方面全新推出的装机系统,这款系统可以通过pe直接的完成安装,对此系统感兴趣,想要使用的用户们就快来下载
微软windows11系统下载 微软原版 Ghost win11 X64 正式版ISO镜像文件
语言:中文版系统大小:0MB系统类型:Win11微软Ghost win11 正式版镜像文件是一款由微软方面推出的优秀全新装机系统,这款系统的新功能非常多,用户们能够在这里体验到最富有人性化的设计等,且全新的柔软界面,看起来非常的舒服~微软Ghost win11 正式版镜像文件介绍:1、与各种硬件设备兼容。 更好地完成用户安装并有效地使用。2、稳定使用蓝屏,系统不再兼容,更能享受无缝的系统服务。3、为
雨林木风Windows11专业版 Ghost Win11官方正式版 (22H2) 系统下载
语言:中文版系统大小:4.75GB系统类型:雨林木风Windows11专业版 Ghost Win11官方正式版 (22H2) 系统下载在系统方面技术积累雄厚深耕多年,打造了国内重装系统行业的雨林木风品牌,其系统口碑得到许多人认可,积累了广大的用户群体,雨林木风是一款稳定流畅的系统,一直以来都以用户为中心,是由雨林木风团队推出的Windows11国内镜像版,基于国内用户的习惯,做了系统性能的优化,采用了新的系统
雨林木风win7旗舰版系统下载 win7 32位旗舰版 GHOST 免激活镜像ISO
语言:中文版系统大小:5.91GB系统类型:Win7雨林木风win7旗舰版系统下载 win7 32位旗舰版 GHOST 免激活镜像ISO在系统方面技术积累雄厚深耕多年,加固了系统安全策略,雨林木风win7旗舰版系统在家用办公上跑分表现都是非常优秀,完美的兼容各种硬件和软件,运行环境安全可靠稳定。win7 32位旗舰装机版 v2019 05能够帮助用户们进行系统的一键安装、快速装机等,系统中的内容全面,能够为广大用户
相关文章
- 电脑中的热键是什么意思?
- Win8系统笔记本提高散热性能的办法
- 不可预料的压缩文件末端,教您解压文件出现不可预料的压缩文件末端
- 微信如何预约车辆年检?预约车辆年检的操作步骤
- 小白教你小米笔记本触摸板没反应怎么办
- XP系统怎样安装JAVA编程环境?JAVA运行环境设置办法详细说明
- 怎样重装被删除的内置应用?Win10恢复内置应用的办法
- 电脑系统下载官网是什么的详细介绍
- 装机高手教你电脑开不了机怎样重装windows7系统旗
- Win8迅速清理系统垃圾的办法
- Win8系统怎样通过Web凭据找到账户密码?
- 怎样迅速保存Windows10聚焦壁纸?
- Win10怎么注册商店账户?win10微软商店账号注册教程
- re文件管理器,本文教您re文件管理器怎样用
- WinXP更新显卡驱动后出现花屏如何处理
- 怎么设置win11耳机默认音量 win11耳机默认音量设置方法【详解】
- 最新win7系统无线网卡驱动重装教程【图文】
- XP开机音乐怎样设置?怎样设置电脑开机音乐?
热门系统
- 1华硕笔记本&台式机专用系统 GhostWin7 32位正式旗舰版2018年8月(32位)ISO镜像下载
- 2深度技术 Windows 10 x86 企业版 电脑城装机版2018年10月(32位) ISO镜像免费下载
- 3电脑公司 装机专用系统Windows10 x86喜迎国庆 企业版2020年10月(32位) ISO镜像快速下载
- 4深度技术 Windows 10 x86 企业版 六一节 电脑城装机版 版本1903 2022年6月(32位) ISO镜像免费下载
- 5雨林木风 Ghost Win7 SP1 装机版 2020年4月(32位) 提供下载
- 6深度技术 Windows 10 x64 企业版 电脑城装机版2021年1月(64位) 高速下载
- 7新萝卜家园电脑城专用系统 Windows10 x64 企业版2019年10月(64位) ISO镜像免费下载
- 8新萝卜家园 GhostWin7 SP1 最新电脑城极速装机版2018年8月(32位)ISO镜像下载
- 9电脑公司Ghost Win8.1 x32 精选纯净版2022年5月(免激活) ISO镜像高速下载
- 10新萝卜家园Ghost Win8.1 X32 最新纯净版2018年05(自动激活) ISO镜像免费下载
热门文章
常用系统
- 1深度技术 GHOST XP SP3 完美装机版 V2016.06 下载
- 2深度技术 GHOST WIN7 SP1 X86 官方优化版 V2016.06(32位) 下载
- 3笔记本&台式机专用系统 Windows10 企业正式版 2018年8月(64位)ISO镜像下载
- 4雨林木风Ghost Win10 64位 纯净版v2023.05
- 5萝卜家园 GHOST WIN10 X86 完美装机版 V2019.10 (32位) 下载
- 6Win7精简版下载_Win7 64位精简版旧电脑专用系统2023.10下载
- 7番茄花园Ghost Win10 热门纯净版x64 v2023.01最新下载
- 8Win10 32位旗舰版下载_Ghost Win10 32位旗舰版镜像下载
- 9Win11 22H2原版镜像下载_Win11 22H2正式版官方镜像下载22621
- 10笔记本&台式机专用系统 GhostWin7 32位旗舰版2020年5月(32位) ISO镜像免费下载