信号量作为同步使用
创建一个Semaphore对象,并指定一个初始的计数值(通常称为“许可”或“令牌”的数量)。这个计数值表示当前可用的资源数量或可以同时访问共享资源的线程数。当一个线程需要访问共享资源时,它会尝试从Semaphore对象中获取一个许可。如果Semaphore的当前计数值大于0,线程会立即获得一个许可,并且计数值减1。线程现在可以安全地访问共享资源。如果Semaphore的当前计数值为0(表示没有可用的许可),线程会被阻塞(挂起),直到有其他线程释放一个许可。acquire方法通常支持超时机制,即线程在尝试获取许可时可以指定一个超时时间。如果在这个时间内没有获取到许可,线程可以选择继续等待、抛出异常或返回表示失败的状态。当线程完成对共享资源的访问后,它会释放之前获取的许可。线程通过调用Semaphore对象的release方法来释放许可。这个方法会将Semaphore的计数值加1,表示有一个新的许可可用。如果有其他线程正在等待获取许可,release方法会唤醒其中一个线程,并使其能够继续执行。
Semaphore API
API名称 | 说明 |
osSemaphoreNew | 创建并初始化一个信号量 |
osSemaphoreGetName | 获取一个信号量的名字 |
osSemaphoreAcquire | 获取一个信号量的令牌,若获取不到,则会超时返回 |
osSemaphoreRelease | 释放一个信号量的令牌,但是令牌的数量不超过初始定义的的令牌数 |
osSemaphoreGetCount | 获取当前的信号量令牌数 |
osSemaphoreDelete | 删除一个信号量 |
代码编写
修改D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\BUILD.gn文件
# Copyright (c) 2023 Beijing HuaQing YuanJian Education Technology Co., Ltd
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/lite/config/component/lite_component.gni")
lite_component("demo") {
features = [
#"base_00_helloworld:base_helloworld_example",
#"base_01_led:base_led_example",
#"base_02_loopkey:base_loopkey_example",
#"base_03_irqkey:base_irqkey_example",
#"base_04_adc:base_adc_example",
#"base_05_pwm:base_pwm_example",
#"base_06_ssd1306:base_ssd1306_example",
#"kernel_01_task:kernel_task_example",
#"kernel_02_timer:kernel_timer_example",
#"kernel_03_event:kernel_event_example",
#"kernel_04_mutex:kernel_mutex_example",
#"kernel_05_semaphore_as_mutex:kernel_semaphore_as_mutex_example",
"kernel_06_semaphore_for_sync:kernel_semaphore_for_sync_example",
]
}
创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\kernel_06_semaphore_for_sync文件夹
文件夹中创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\kernel_06_semaphore_for_sync\kernel_semaphore_as_mutex_example.c文件D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\kernel_06_semaphore_for_sync\BUILD.gn文件
# Copyright (c) 2023 Beijing HuaQing YuanJian Education Technology Co., Ltd
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("kernel_semaphore_for_sync_example") {
sources = [
"kernel_semaphore_for_sync_example.c"
]
include_dirs = [
"//utils/native/lite/include",
"//kernel/liteos_m/kal/cmsis",
]
}
/*
* Copyright (c) 2023 Beijing HuaQing YuanJian Education Technology Co., Ltd
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
osThreadId_t Task1_ID; // 任务1 ID
osThreadId_t Task2_ID; // 任务2 ID
osSemaphoreId_t Semaphore_ID; // 信号量ID
#define TASK_STACK_SIZE 1024
#define TASK1_DELAY_TIME 1
#define TASK2_DELAY_TIME 2
/**
* @description: 任务1
* @param {*}
* @return {*}
*/
void Task1(void)
{
while (1) {
osSemaphoreAcquire(Semaphore_ID, osWaitForever); // 请求信号量 -1
printf("Task 1 osSemaphore Acquire <=====\n");
sleep(TASK1_DELAY_TIME);
}
}
/**
* @description: 任务2
* @param {*}
* @return {*}
*/
void Task2(void)
{
while (1) {
osSemaphoreRelease(Semaphore_ID); // 释放信号量 +1
printf("Task 2 osSemaphore Release =====>\n");
sleep(TASK2_DELAY_TIME);
}
}
/**
* @description: 初始化并创建任务
* @param {*}
* @return {*}
*/
static void kernel_sync_semaphore_example(void)
{
printf("Enter kernel_sync_semaphore_example()!\n");
// 创建信号量
Semaphore_ID = osSemaphoreNew(1, 0, NULL); // 参数: 最大计数值,初始计数值,参数配置
if (Semaphore_ID != NULL) {
printf("ID = %d, Create Semaphore_ID is OK!\n", Semaphore_ID);
}
osThreadAttr_t taskOptions;
taskOptions.name = "Task1"; // 任务的名字
taskOptions.attr_bits = 0; // 属性位
taskOptions.cb_mem = NULL; // 堆空间地址
taskOptions.cb_size = 0; // 堆空间大小
taskOptions.stack_mem = NULL; // 栈空间地址
taskOptions.stack_size = TASK_STACK_SIZE; // 栈空间大小 单位:字节
taskOptions.priority = osPriorityNormal; // 任务的优先级
Task1_ID = osThreadNew((osThreadFunc_t)Task1, NULL, &taskOptions); // 创建任务1
if (Task1_ID != NULL) {
printf("ID = %d, Create Task1_ID is OK!\n", Task1_ID);
}
taskOptions.name = "Task2"; // 任务的名字
taskOptions.priority = osPriorityNormal; // 任务的优先级
Task2_ID = osThreadNew((osThreadFunc_t)Task2, NULL, &taskOptions); // 创建任务2
if (Task2_ID != NULL) {
printf("ID = %d, Create Task2_ID is OK!\n", Task2_ID);
}
}
SYS_RUN(kernel_sync_semaphore_example);
使用build,编译成功后,使用upload进行烧录。