RT-Thread OS 信号量创建以及IPC使用

//多个线程操作 / 访问同一块区域(代码),这块代码就称为临界区,在访问临界区的时候只允许一个 (或一类) 线程运行
//当多个线程都要使用临界区资源时,任何时刻最多只允许一个线程去使用,其它要使用该资源的线程必须等待,直到占用资源者释放该资源。
//线程互斥可以看成是一种特殊的线程同步。

#include <rtthread.h>

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

rt_sem_t sem1_handle = NULL;
struct rt_semaphore sem2;
rt_thread_t th1 = NULL,th2 = NULL;

int flag = 1;  //临界资源

//IPC flags and control command definitions
//    rt_sem_create(name, value, flag);

//信号量创建flag
//#define RT_IPC_FLAG_FIFO                0x00            /**< FIFOed IPC. @ref IPC. */
//#define RT_IPC_FLAG_PRIO                0x01            /**< PRIOed IPC. @ref IPC. */

//信号量获取flag
//#define RT_WAITING_FOREVER              -1              /**< Block forever until get resource. */
//#define RT_WAITING_NO                   0               /**< Non-block. */
void th1_entry(void *parameter)
{

   //如果信号量2的值>0, flag++
    while(1)
    {
         rt_sem_take(&sem2, RT_WAITING_FOREVER);
         flag++;
         if(flag == 100)  flag = 0;
         rt_kprintf("th1_entry falg = %d\n",flag);
         rt_sem_release(sem1_handle); //释放信号量1.让线程2可以运行
         rt_thread_mdelay(1000);
    }


}
void th2_entry(void *parameter)
{
   //信号量1的值大于0时,线程2才可以执行,否则挂起
    while(1)
    {
          rt_sem_take(sem1_handle, RT_WAITING_FOREVER);
          flag--;
          if(flag <0 )  flag = 100;
          rt_kprintf("th2_entry falg = %d\n",flag);
          rt_sem_release(&sem2);//释放信号量2.让线程1可以运行
          rt_thread_mdelay(1000);
    }

}
int main(void)
{
    //动态信号量创建
    sem1_handle = rt_sem_create("sem1", 1, RT_IPC_FLAG_FIFO);//信号量值为1,线程2可以执行
    if(sem1_handle == RT_NULL){
        LOG_E("sem1 rt_sem_create failed...\n");
        return RT_ERROR;
    }
    LOG_D("sem1 rt_sem_create successed...\n");
    //静态创建信号量
    rt_err_t ret ;
    ret = rt_sem_init(&sem2,"sem2", 0, RT_IPC_FLAG_FIFO);//信号量值为0,线程1不可以执行
    if(ret != RT_EOK){
        LOG_E("sem2 rt_sem_init failed...\n");
        return ret;
    }
    LOG_D("sem2 rt_sem_init successed...\n");
//创建两个线程用来访问临界区域
    th1 = rt_thread_create("th1", th1_entry, NULL, 512, 20, 5);
    if(th1 == RT_NULL){
        LOG_E("th1 rt_thread_create failed...\n");
        return RT_ENOMEM;
    }
    LOG_D("th1 rt_thread_create successed...\n");
    rt_thread_startup(th1);

    th2 = rt_thread_create("th2", th2_entry, NULL, 512, 20, 5);
        if(th2 == RT_NULL){
            LOG_E("th2 rt_thread_create failed...\n");
            return RT_ENOMEM;
        }
    LOG_D("th2 rt_thread_create successed...\n");
    rt_thread_startup(th2);

    return RT_EOK;
}

程序运行结果

[2022-10-25_16:38:10:973]- RT -     Thread Operating System
[2022-10-25_16:38:10:973] / | \     4.0.3 build Oct 24 2022
[2022-10-25_16:38:10:973] 2006 - 2020 Copyright by rt-thread team
[2022-10-25_16:38:10:973][0m[D/main] sem1 rt_sem_create successed...
[2022-10-25_16:38:10:973][0m
[2022-10-25_16:38:10:973][0m[D/main] sem2 rt_sem_init successed...
[2022-10-25_16:38:10:973][0m
[2022-10-25_16:38:10:973][0m[D/main] th1 rt_thread_create successed...
[2022-10-25_16:38:10:991][0m
[2022-10-25_16:38:10:991][0m[D/main] th2 rt_thread_create successed...
[2022-10-25_16:38:10:991][0m
[2022-10-25_16:38:10:991]msh >th2_entry falg = 0
[2022-10-25_16:38:10:991]th1_entry falg = 1
[2022-10-25_16:38:12:000]th2_entry falg = 0
[2022-10-25_16:38:12:000]th1_entry falg = 1
[2022-10-25_16:38:12:997]th2_entry falg = 0
[2022-10-25_16:38:12:997]th1_entry falg = 1
线程2和线程1会轮流循环得到执行,所以flag的0为0->1,0->1变化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值