线程间同步之事件集

1. 示例代码

/*
 * Copyright (c) 2006-2020, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-02-07     冷月枫       the first version
 */
/* 初始化一个事件集,两个线程。一个线程等待自己关心的事件发生,另一个线程发送事件 */
#include <rtthread.h>

#define THREAD_PRIORITY      9
#define THREAD_TIMESLICE     5

ALIGN(RT_ALIGN_SIZE)
static char thread1_stack[1024];
static struct rt_thread thread1;

ALIGN(RT_ALIGN_SIZE)
static char thread2_stack[1024];
static struct rt_thread thread2;

#define EVENT_FLAG3 (1 << 3)
#define EVENT_FLAG5 (1 << 5)

/* 事件控制块 */
static struct rt_event event;


/* 线程1入口函数 */
static void thread1_recv_evnt(void* parameter)
{
  rt_uint32_t e;

  /* 第一次接收事件, 事件3或事件5任意一个都可以触发线程1  接收完后清除事件标志 */
  if(rt_event_recv(&event,   // 事件控制块
                   (EVENT_FLAG3|EVENT_FLAG5),  // 操作的事件
                   RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,  // 或操作并且清除
                   RT_WAITING_FOREVER,  // 超时时间 永久
                   &e) == RT_EOK); // 指向接收的事件
  {
      rt_kprintf("thread1 OR recv event 0x%x\n",e);
  }

  rt_kprintf("thread1 delay 1s to prepare the second event\n");
  rt_thread_mdelay(1000);

  /* 第二次接收事件,事件3和事件5同时发生才可以触发线程1,接收完后清除事件标志 */
  if(rt_event_recv(&event,   // 事件控制块
                   (EVENT_FLAG3|EVENT_FLAG5),  // 操作的事件
                   RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR,  // 或操作并且清除
                   RT_WAITING_FOREVER,  // 超时时间 永久
                   &e) == RT_EOK); // 指向接收的事件
  {
      rt_kprintf("thread1 AND recv event 0x%x\n",e);
  }
  rt_kprintf("thread1 leave\n");
}

/* 线程2的入口函数 */
static void thread2_send_event(void*param)
{
    rt_kprintf("thread2 send event3\n");
    rt_event_send(&event,EVENT_FLAG3);  // 发送事件3
    rt_thread_mdelay(200); // 延时200ms

    rt_kprintf("thread2 send event5\n");
    rt_event_send(&event,EVENT_FLAG5);  // 发送事件5
    rt_thread_mdelay(200); // 延时200ms

    rt_kprintf("thread2 send event3\n");
    rt_event_send(&event,EVENT_FLAG3);  // 发送事件3
    rt_kprintf("thread2 leave\n");
}

/* 事件初始化 */
int event_sample(void)
{
  rt_err_t re;

  /* 初始化事件对象 */
  re = rt_event_init(&event, // 事件控制块
                     "event",  // 事件名称
                     RT_IPC_FLAG_FIFO); // 事件操作
  if(re != RT_EOK) // 创建事件失败
  {
      rt_kprintf("init event failed\n");
      return -1;
  }

  /* 线程1 */
     rt_thread_init(&thread1,   // 线程控制块
                     "thread1",  // 线程名
                     thread1_recv_evnt,  // 线程入口函数
                     RT_NULL,  // 入口函数的参数
                     thread1_stack,  // 线程堆栈
                     sizeof(thread1_stack), // 线程大小
                     THREAD_PRIORITY - 1, // 线程优先级
                     THREAD_TIMESLICE); // 线程时间片
     rt_thread_startup(&thread1);  // 启动线程

     /* 线程2 */
        rt_thread_init(&thread2,   // 线程控制块
                        "thread2",  // 线程名
                        thread2_send_event,  // 线程入口函数
                        RT_NULL,  // 入口函数的参数
                        thread2_stack,  // 线程堆栈
                        sizeof(thread2_stack), // 线程大小
                        THREAD_PRIORITY, // 线程优先级
                        THREAD_TIMESLICE); // 线程时间片
        rt_thread_startup(&thread2);  // 启动线程

        return 0;
}
/* 导出到msh命令列表中 */
MSH_CMD_EXPORT(event_sample,event sample);

2.测试结果

在这里插入图片描述

详细文档
链接

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值