2024.4.3

1.除了队列和信号量,FreeRTOS使用哪些其他机制来实现任务间通信?
使用互斥锁,互斥锁是一种用于保护共享资源的机制。当一个任务需要使用一个共享资源时,它必须首先获取互斥锁。如果互斥锁已经被另一个任务获取,那么这个任务就需要等待,直到互斥锁被释放。在FreeRTOS中,可以使用xSemaphoreCreateMutex()函数来创建一个互斥锁。
使用事件标志组,事件标志组是一种用于表示一组事件发生状态的数据结构。每一个事件都有一个对应的标志,当事件发生时,标志被设置,当事件被处理时,标志被清除。在FreeRTOS中,可以使用xEventGroupCreate()函数来创建一个事件标志组。
2.直接任务通知是什么,如何使用它们?
任务通知是RTOS中常用的用于任务间交互的功能。发送通知的函数需要设置为1
3.总结二进制信号量和计数型信号量的区别,以及他们的使用场景。
(1)二进制信号量:最快和常用的信号量,提供阻塞方式,用于实现同步或互斥。计数信号量:类似于二进制信号量,记录信号量被释放的次数。适合于一个资源的个实例需要保护的情况。
(2)二进制信号量可以用来进行同步和互斥,没有优先级反转保护,不支持优先级继承协议和嵌套;而且对于二进制信号量,不同的任务都可以对其进行释放,在中断任务中也可以释放二进制信号量,甚至当任务持有二进制信号量时,其它任务都可以删除它。
(3)计数器信号量使用一个计数器,允许多次获取和释放信号量,用于操作系统中共享资源的多个任务的使用,是实现同步与互斥的另一种手段,适用于保护多份复制的资源。与二进制信号量相同的是,如果信号量被释放时存在被阻塞的任务,那么被阻塞的任务将被解除阻塞。与二进制信号量不同的是,它还跟踪信号量被释放的次数,每释放一个信号量,计数器加一,每提取一个信号量,计数器减一。如果信号量被释放时不存在阻塞的任务,那么计数器将加一,这意味着一个被释放两次的信号量可以无阻塞地被提取两次。
4.总结FreeRTOS中同步和互斥的五种方法的使用方法
队列可以用于"任务到任务"、“任务到中断”、"中断到任务"直接传输信息。
信号量只需要维护一个数值,使用信号量效率更高、更节省内存
互斥量用于临界资源的保护一般建议使用互斥量。
事件组一个 32 位的事件集合,其中的每一位都可以表示一个事件.每一位事件的含义由程序员决定,比如:Bit0 表示用来串口是否就绪,Bit1 表示按键是否被按下
任务通知在 FreeRTOS 中,每一个任务都有两个用于任务通知功能的数组,分别为 " 任务通知数组 " 和 " 任务通知状态数组 " 。
5.总结任务通知和其他任务通信机制的区别
任务通知与其他通信方式的区别 使用队列、信号量、事件组时,我们都要事先创建对应的结构体,双方通过中间的结构体通信: 但我们的任务通知只需要对方的TCB结构体即可任务结构体 TCB 中就包含了内部对象,可以直接接收别人发过来的"通知"
6.生产者和消费者模型

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
 
#define BUFFER_SIZE 5
 
int buffer[BUFFER_SIZE];
int in = 0;
int out = 0;
 
sem_t empty;  
sem_t full;   
pthread_mutex_t mutex;  // 互斥锁
 
void *producer(void *arg) {
    int item = 1;
    while (1) {
        sem_wait(&empty);  
        pthread_mutex_lock(&mutex);  
 
        // 生产
        buffer[in] = item;
        printf("Producer produced item %d\n", item);
        in = (in + 1) % BUFFER_SIZE;
        item++;
 
        pthread_mutex_unlock(&mutex);  
        sem_post(&full);  
    }
}
 
void *consumer(void *arg) {
    while (1) {
        sem_wait(&full);  
        pthread_mutex_lock(&mutex);  
 
        // 消费
        int item = buffer[out];
        printf("Consumer consumed item %d\n", item);
        out = (out + 1) % BUFFER_SIZE;
 
        pthread_mutex_unlock(&mutex);  
        sem_post(&empty);  
    }
}
 
int main() {
    pthread_t producer_thread, consumer_thread;
 
    // 初始化
    sem_init(&empty, 0, BUFFER_SIZE);
    sem_init(&full, 0, 0);
    pthread_mutex_init(&mutex, NULL);
 
    // 创建生产者和消费者线程
    pthread_create(&producer_thread, NULL, producer, NULL);
    pthread_create(&consumer_thread, NULL, consumer, NULL);
    pthread_join(producer_thread, NULL);
    pthread_join(consumer_thread, NULL);
  // 销毁
    sem_destroy(&empty);
    sem_destroy(&full);
    pthread_mutex_destroy(&mutex);
 
    return 0;
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值