基于OpenHarmony标准系统的C++公共基础类库案例:Semaphore 原创 精华
1、程序简介
该程序是基于OpenHarmony标准系统的C++公共基础类库的线程处理:Sempahore。
本案例完成如下工作:
(1)无名信号量使用方法
-
定义1个无名信号量,1个供无名信号量管理的公共资源变量;
-
创建5个线程,每个线程做5次for循环,for循环的内容是获取无名信号量,并修改公共资源变量;
(2)有名信号量使用方法
- 定义1个有名信号量,1个供有名信号量管理的公共资源变量;
- 创建1个线程A,通过Open获取信号量,做5次for循环,for循环的内容是通过Wait获取有名信号量,如果获取成功则修改公共资源变量(即累加1),最后释放信号量;
- 创建1个线程B,通过Open获取信号量,做5次for循环,for循环的内容是通过TryWait获取有名信号量,如果获取成功则修改公共资源变量(即累加10),最后释放信号量;
- 创建1个线程C,通过Open获取信号量,做5次for循环,for循环的内容是通过TimedWait获取有名信号量,如果获取成功则修改公共资源变量(即累加100),最后释放信号量;
2、基础知识
C公共基础类库为标准系统提供了一些常用的C开发工具类,包括:
- 文件、路径、字符串相关操作的能力增强接口
- 读写锁、信号量、定时器、线程增强及线程池等接口
- 安全数据容器、数据序列化等接口
- 各子系统的错误码相关定义
2.1、添加C++公共基础类库依赖
修改需调用模块的BUILD.gn,在external_deps或deps中添加如下:
一般而言,我们只需要填写"c_utils:utils"即可。
2.2、Semaphore头文件
C++公共基础类库的Semaphore头文件在://commonlibrary/c_utils/base/include/semaphore_ex.h
可在源代码中添加如下:
OpenHarmony信号量根据种类可以分为有名信号量和无名信号量,所以命令空间如下:
(1)无名信号量命名空间
(2)有名信号量命名空间
2.3、OHOS::Samaphore接口说明
Semaphore为无名信号量。
2.3.1、Samaphore
构造函数, 构造一个Samaphore对象。
参数说明:
参数名称 | 类型 | 参数说明 |
---|---|---|
value | int | 信号量当前资源数量 |
2.3.2、~Semaphore
析构函数。
2.3.3、Wait
等待/获取信号量(即信号量 -1)。
2.3.4、Post
释放信号量(即信号量 +1)。
2.4、OHOS::NamedSemaphore接口说明
NamedSemaphore为有名信号量。
2.4.1、NamedSemaphore
构造函数, 构造NamedSemaphore对象。
参数说明:
参数名称 | 类型 | 参数说明 |
---|---|---|
name | std::string | 信号量名称 |
size | size_t | 信号量有效资源数量 |
2.4.2、~NamedSemaphore
析构函数。
2.4.3、Create
创建并初始化有名信号量。
返回值说明:
类型 | 返回值说明 |
---|---|
bool | true表示成功,false表示失败 |
2.4.4、Unlink
将有名信号量文件从系统中删除。
返回值说明:
类型 | 返回值说明 |
---|---|
bool | true表示成功,false表示失败 |
2.4.5、Open
打开一个已经创建的有名信号量文件。
返回值说明:
类型 | 返回值说明 |
---|---|
bool | true表示成功,false表示失败 |
2.4.6、Close
关闭有名信号量。
返回值说明:
类型 | 返回值说明 |
---|---|
bool | true表示成功,false表示失败 |
2.4.7、Wait
等待/获取信号量(信号量 -1)。
返回值说明:
类型 | 返回值说明 |
---|---|
bool | true表示成功,false表示失败 |
2.4.8、TryWait
等待/获取信号量(信号量 -1)的接口;非阻塞版。
返回值说明:
类型 | 返回值说明 |
---|---|
bool | true表示成功,false表示失败 |
2.4.9、TimedWait
等待/获取信号量(信号量 -1);指定阻塞时间版。
参数说明:
参数名称 | 类型 | 参数说明 |
---|---|---|
ts | struct timespec | 绝对时间。注意:ts是utc时间,不是相对时间。 |
返回值说明:
类型 | 返回值说明 |
---|---|
bool | true表示成功,false表示失败 |
2.4.10、Post
释放信号量(信号量 +1)。
返回值说明:
类型 | 返回值说明 |
---|---|
bool | true表示成功,false表示失败 |
2.4.10、GetValue
获取信号的值。
返回值说明:
类型 | 返回值说明 |
---|---|
int | 返回当前信号量的值 |
3、程序解析
3.1、创建编译引导
在//vendor/lockzhiner/rk3568/samples/BUILD.gn文件添加一行编译引导语句。
"a24_utils_semaphore:utils_semaphore",
该行语句表示引入参与编译。
3.2、创建编译项目
创建a24_utils_semaphore目录,并添加如下文件:
3.3、创建BUILD.gn
编辑BUILD.gn文件。
添加2个可执行程序,分别是:
- utils_noname_semaphore:无名信号量使用案例
- utils_name_semaphore:有名信号量使用案例
注意:
(1)BUILD.gn中所有的TAB键必须转化为空格,否则会报错。如果自己不知道如何规范化,可以:
3.4、无名信号量使用案例
3.4.1、添加信号量头文件
3.4.2、创建无名信号量以及公共资源变量
3.4.3、创建线程池
3.4.4、设置线程池
3.4.5、启动线程
3.4.6、编写子线程代码
循环5次,每次循环调用信号量Wait()等待获取信号量。如果获取信号量后,将公共资源变量累加,调用信号量Post()释放信号量。
3.5、有名信号量使用案例
3.5.1、添加信号量头文件
3.5.2、创建有名信号量
首先定义有名信号量,然后通过Create()创建全局有名信号量。
3.5.3、创建线程池
通过OHOS::ThreadPool定义线程池,调用SetMaxTaskNum()设置线程池最大线程数,并调用Start()设置当前启动多少个线程。
3.5.4、启动子线程A、B和C
3.5.5、编写子线程A
首先定义有名信号量,信号量数目可以随意设置。
其次,通过Open()打开有名信号量,可以与main()的有名信号量共享同一个信号量。
最后,通过Wait()和Post()来获取释放信号量。
3.5.6、编写子线程B
首先定义有名信号量,信号量数目可以随意设置。
其次,通过Open()打开有名信号量,可以与main()的有名信号量共享同一个信号量。
最后,通过TryWait()和Post()来获取释放信号量。
3.5.7、编写子线程C
首先定义有名信号量,信号量数目可以随意设置。
其次,通过Open()打开有名信号量,可以与main()的有名信号量共享同一个信号量。
最后,通过TimedWait()和Post()来获取释放信号量。
4、编译步骤
进入OpenHarmony编译环境,运行如下命令:
将镜像烧录到开发板中。
5、运行结果
5.1、无名信号量
运行结果如下:
5.2、有名信号量
运行结果如下:
很完整的实例分享,感谢讲解