当前位置: 首页 > wzjs >正文

四川省城镇建设二次供水网站南京尔顺科技发展有限公司表扬信息南京seo关键词优化预订

四川省城镇建设二次供水网站南京尔顺科技发展有限公司表扬信息,南京seo关键词优化预订,湖南建设人才网官网,长春网站建设与健在读FreeRTOS内核实现与应用开发实战指南的时候,书中第16章有这么一句话:可以将二值信号量看作只有一个消息的队列,incident这个队列只能为空或满(因此称为二值),在运用时只需要之傲队列中是否由消息即可&a…

在读FreeRTOS内核实现与应用开发实战指南的时候,书中第16章有这么一句话:可以将二值信号量看作只有一个消息的队列,incident这个队列只能为空或满(因此称为二值),在运用时只需要之傲队列中是否由消息即可,而无需关注消息是什么。

虽然原书写的是二值信号量与队列之间的关系,但两个东西也容易搞混,遂看了下区别。

文章目录

  • 省流回答
      • 1. 定义
      • 2. 行为差异
      • 3. 是否可以相互替代?
        • 场景 1:用信号量模拟消息队列
        • 场景 2:用消息队列模拟信号量
      • 4. 典型应用场景
  • 比喻理解: 二值信号量与消息队列:用“钥匙”和“信箱”理解同步与通信
    • 一、形象比喻:钥匙 vs 信箱
      • 1. 二值信号量:一把共享的钥匙
      • 2. 消息队列:一个共享的信箱
    • 二、对比与示例解析
      • 示例1:钥匙的互斥控制(二值信号量)
      • 示例2:信箱的数据传递(消息队列)
    • 三、常见误区:用错工具的代价
      • 1. 误区:用钥匙传递秘密指令(用信号量传数据)
      • 2. 误区:用信箱当钥匙(用队列实现锁)
    • 四、高效组合:钥匙 + 信箱(信号量 + 队列)
      • 场景:餐厅订单系统
    • 五、总结表格:钥匙 vs 信箱
    • 六、终极选择原则

二值信号量不能被视为消息队列。两者的设计目标和功能截然不同:

  • 信号量是 状态标记,解决“是否可用”或“何时触发”的问题。
  • 消息队列是 数据通道,解决“传递什么信息”的问题。

若需同时实现 同步 + 数据传递,可以组合使用二者(例如用信号量通知消息到达,用队列传递数据),或直接使用更高级的机制(如事件标志组 + 消息队列)。


省流回答

1. 定义

  • 二值信号量
    主要用于 同步互斥控制,通过 01 的二进制状态传递简单的“资源可用性”或“事件触发”信号。

  • 同步:例如任务 A 完成任务后释放信号量,告知任务 B 可以开始工作。

  • 互斥:例如保护共享资源(如一段代码或硬件外设),确保同一时间只有一个任务能访问。

  • 消息队列
    主要用于 任务间通信,允许传递带有数据的结构化消息。

    • 发送方将数据(如传感器读数、命令等)封装成消息并放入队列。
    • 接收方从队列中获取消息并解析数据,完成信息传递。

2. 行为差异

特性二值信号量消息队列
数据传递无数据,仅状态(0/1)可携带任意数据(结构体、指针等)
状态持久性信号量被获取后状态归零消息被读取后从队列中移除
容量仅一个状态位(0或1)可容纳多个消息(队列长度可配置)
阻塞行为任务等待信号量时可能阻塞任务等待消息时可能阻塞
优先级继承可能支持(用于避免优先级反转)通常不支持

3. 是否可以相互替代?

场景 1:用信号量模拟消息队列

理论上可以通过多次释放信号量(类似“计数信号量”)表示多个事件,但存在以下问题:

  • 无法传递数据:接收方只知道“有事件发生”,但无法获取具体信息(例如事件类型、参数等)。
  • 状态丢失风险:若发送方快速多次释放信号量,可能导致接收方错过计数(二值信号量只能记录有无,无法累积)。
场景 2:用消息队列模拟信号量

可以通过发送空消息(无实际数据)模拟信号量,但会引入额外开销:

  • 资源浪费:消息队列需要内存存储消息头和数据,而信号量仅需一个状态位。
  • 复杂度增加:需约定空消息的语义,降低代码可读性。

4. 典型应用场景

  • 二值信号量适用场景

    • 保护共享资源(如串口打印函数)。
    • 任务间简单同步(如任务 A 完成后触发任务 B)。
  • 消息队列适用场景

    • 传递传感器数据(如温度、湿度数值)。
    • 发送控制命令(如“开启电机”、“调整参数”)。
    • 多任务协作处理复杂数据流。

比喻理解: 二值信号量与消息队列:用“钥匙”和“信箱”理解同步与通信


一、形象比喻:钥匙 vs 信箱

1. 二值信号量:一把共享的钥匙

想象你有一个需要多人轮流使用的会议室,但会议室的门只有一把钥匙。这把钥匙就是 二值信号量

  • 钥匙在桌上(信号量为1):表示会议室空闲,任何人都可以取钥匙进入。
  • 钥匙被拿走(信号量为0):表示会议室被占用,其他人必须等待钥匙归还。

这种机制保证了 互斥访问(同一时间只有一人使用会议室),但钥匙本身不传递任何信息(比如谁在使用会议室或用了多久)。


2. 消息队列:一个共享的信箱

假设你有两个同事在不同楼层办公,他们通过一个 物理信箱 传递文件:

  • 发送方:将文件投入信箱(xQueueSend)。
  • 接收方:从信箱取文件(xQueueReceive)。

信箱可以容纳多个文件(队列长度可配置),且每个文件都包含具体内容(数据)。即使接收方暂时不在,文件也会保留在信箱中,避免数据丢失。


二、对比与示例解析

示例1:钥匙的互斥控制(二值信号量)

场景:多个任务共享打印机(避免同时打印混乱)。

SemaphoreHandle_t printer_key = xSemaphoreCreateBinary(); // 钥匙初始在桌上(1)void TaskA() {xSemaphoreTake(printer_key, portMAX_DELAY); // 拿走钥匙printf("TaskA is printing...\n"); xSemaphoreGive(printer_key);                // 归还钥匙
}void TaskB() {xSemaphoreTake(printer_key, portMAX_DELAY); // 等待钥匙printf("TaskB is printing...\n"); xSemaphoreGive(printer_key);                // 归还钥匙
}

比喻解释

  • 打印机是共享资源,钥匙(信号量)确保同一时间只有一个任务能打印。
  • 钥匙不携带信息,只控制访问权限。

示例2:信箱的数据传递(消息队列)

场景:温度传感器任务发送数据到控制任务。

QueueHandle_t temperature_mailbox = xQueueCreate(5, sizeof(float)); // 信箱最多5封信void SensorTask() {float temp = read_sensor();xQueueSend(temperature_mailbox, &temp, portMAX_DELAY); // 投递“温度信”
}void ControlTask() {float received_temp;xQueueReceive(temperature_mailbox, &received_temp, portMAX_DELAY); // 取信adjust_fan(received_temp); // 根据信的内容行动
}

比喻解释

  • 每封信(消息)包含具体的温度值(数据)。
  • 信箱(队列)缓存信件,即使控制任务繁忙,数据也不会丢失。

三、常见误区:用错工具的代价

1. 误区:用钥匙传递秘密指令(用信号量传数据)

假设你试图通过钥匙传递“今天中午吃什么”的信息:

// 错误代码:用信号量传递午餐命令
SemaphoreHandle_t lunch_key = xSemaphoreCreateBinary();void BossTask() {decide_lunch("pizza"); xSemaphoreGive(lunch_key); // 发送钥匙(但没告诉吃什么!)
}void EmployeeTask() {xSemaphoreTake(lunch_key, portMAX_DELAY);// 员工拿到钥匙,但不知道要吃啥,只能猜!
}

问题:钥匙只能表示“有指令”,但无法传递指令内容。正确做法是用消息队列发送字符串 "pizza"


2. 误区:用信箱当钥匙(用队列实现锁)

假设你用信箱模拟钥匙,要求每次操作前必须取一封信:

QueueHandle_t fake_key = xQueueCreate(1, sizeof(int)); // 信箱里放一把“纸钥匙”void TaskA() {int dummy;xQueueReceive(fake_key, &dummy, portMAX_DELAY); // 取“纸钥匙”access_resource(); xQueueSend(fake_key, &dummy, portMAX_DELAY);    // 放回“纸钥匙”
}

问题:虽然能实现互斥,但浪费内存存储无用的“纸钥匙”,而信号量只需一个状态位。


四、高效组合:钥匙 + 信箱(信号量 + 队列)

场景:餐厅订单系统

  • 钥匙(信号量):服务员收到订单后按铃(xSemaphoreGive),通知厨师有新的订单。
  • 信箱(队列):订单内容(如“牛排5分熟”)通过队列传递。
QueueHandle_t order_box = xQueueCreate(10, sizeof(Order)); 
SemaphoreHandle_t order_bell = xSemaphoreCreateBinary();// 服务员任务
void WaiterTask() {Order order = take_order();         // 记录顾客需求xQueueSend(order_box, &order, 0);   // 将订单放入信箱xSemaphoreGive(order_bell);         // 按铃通知厨师
}// 厨师任务
void ChefTask() {Order current_order;while(1) {xSemaphoreTake(order_bell, portMAX_DELAY); // 等待铃声xQueueReceive(order_box, &current_order, 0); cook(current_order); // 根据订单内容烹饪}
}

优势

  • 铃声(信号量)让厨师立即响应,无需不断检查信箱。
  • 信箱(队列)保存订单详情,避免信息遗漏。

五、总结表格:钥匙 vs 信箱

场景二值信号量(钥匙)消息队列(信箱)组合使用(餐厅系统)
核心功能控制“谁能用”传递“是什么”通知 + 数据传递
数据传递❌ 无✅ 有✅ 有(通过队列)
资源开销极低(一把钥匙)较高(信箱容量 × 消息大小)中等
典型误用试图用钥匙传纸条(丢信息)用信箱排队取钥匙(浪费空间)
正确场景保护打印机、同步任务启动传递传感器数据、用户命令实时通知 + 异步数据处理

六、终极选择原则

  • 需要控制“谁能用”?
    ➔ 用 钥匙(二值信号量)
    (例如:保护共享资源、任务同步)

  • 需要告诉对方“是什么”?
    ➔ 用 信箱(消息队列)
    (例如:传递温度值、发送控制命令)

  • 既要通知对方,又要传递数据?
    组合使用钥匙 + 信箱
    (例如:订单系统、实时数据处理)

通过选择正确的工具,你的代码会像精心设计的机械一样,既高效又可靠!

http://www.dtcms.com/wzjs/90753.html

相关文章:

  • 公司注销后网站备案吗北京seo包年
  • 江苏自助建站系统哪家好最近的国际新闻大事10条
  • wordpress 树形主题指定关键词seo报价
  • yfcmf做网站百度推广总部电话
  • 医院网站建设方案策划书域名注册时间查询
  • 网站被黑解决方案宁波seo优化报价多少
  • 信息技术网站建设专业网站推广方案策划
  • 网站系统怎么做武汉网络推广公司
  • c 网站开发人员工具爱站网站
  • B2B2c机票酒店网站制作建设淘宝seo是指什么
  • 外贸公司企业网站网络营销的概念及特征
  • 怎么做网站劫持百度关键词搜索排名统计
  • 网站内容吸引怎么做才好小熊代刷推广网站
  • 网站建设管理制度九不准网络营销公司热线电话
  • 做网站什么程序今日国际新闻最新消息
  • 外贸建站如何推广艺考培训学校
  • 东莞做汽车有没有买票的网站怎样在百度上发布信息
  • 优质服务的小企业网站建设有哪些推广平台和渠道
  • 如何用区块链加密wordpress搜索引擎优化排名关键字广告
  • 怎么做网站注册名密码成都网站改版优化
  • 系统开发软件有哪些seo推广公司排名
  • 深圳创同盟科技有限公司网站seo技术能不能赚钱
  • 亚马逊网站类型百度获客
  • 查企业企业网站有哪些出售友情链接是什么意思
  • 动易网站首页错位电商平台怎么搭建
  • 广州营销型网站建设公司哪家靠谱福州seo公司排名
  • 武汉做网站哪个公司好网站关键词优化怎么弄
  • 360网站排名怎么做seo网络培训机构
  • 嘉兴网站建设公司郑州网站推广培训
  • 跳蚤市场网站开发背景产品软文范例1000字