信號量作為同步使用
創建一個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); // 請求信號量 -1printf("Task 1 osSemaphore Acquire <=====\n");sleep(TASK1_DELAY_TIME);}
}
/*** @description: 任務2* @param {*}* @return {*}*/
void Task2(void)
{while (1) {osSemaphoreRelease(Semaphore_ID); // 釋放信號量 +1printf("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); // 創建任務1if (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); // 創建任務2if (Task2_ID != NULL) {printf("ID = %d, Create Task2_ID is OK!\n", Task2_ID);}
}
SYS_RUN(kernel_sync_semaphore_example);
使用build,編譯成功后,使用upload進行燒錄。