Zephyr RTOS 中k_mutex(互斥锁)功能介绍

目录

概述

[1 k_mutex的函数](#1 k_mutex的函数)

[1.1 核心互斥锁函数](#1.1 核心互斥锁函数)

[1.2 互斥锁的核心概念](#1.2 互斥锁的核心概念)

[1.3 互斥锁与其他同步机制对比](#1.3 互斥锁与其他同步机制对比)

[2 核心函数与使用](#2 核心函数与使用)

[2.1 初始化互斥锁](#2.1 初始化互斥锁)

[2.2 基本加锁与解锁操作](#2.2 基本加锁与解锁操作)

[2.3 带超时的加锁操作](#2.3 带超时的加锁操作)

[2.4 互斥锁状态查询](#2.4 互斥锁状态查询)

[3 完整应用示例](#3 完整应用示例)

[3.1 保护共享硬件资源](#3.1 保护共享硬件资源)

[3.2 复杂数据结构保护](#3.2 复杂数据结构保护)

[3.3 避免死锁的模式](#3.3 避免死锁的模式)

[3.4 调试与性能分析](#3.4 调试与性能分析)

[3.5 错误处理模式](#3.5 错误处理模式)

[3.6 调试函数](#3.6 调试函数)

[4 应用总结](#4 应用总结)

[4.1 常见陷阱与解决方案](#4.1 常见陷阱与解决方案)

[4.2 配置](#4.2 配置)

[4.3 特性总结](#4.3 特性总结)


概述

在 Zephyr RTOS 中,k_mutex(互斥锁)是用于保护共享资源 ,防止多个线程同时访问导致数据竞争的核心同步机制 。它确保在任何时刻,只有一个线程可以进入被保护的代码区域(临界区)。

1 k_mutex的函数

1.1 核心互斥锁函数

函数 功能描述 主要用途
k_mutex_init() 动态初始化互斥锁 运行时初始化互斥锁
k_mutex_lock() 获取互斥锁(加锁) 进入临界区前获取锁
k_mutex_unlock() 释放互斥锁(解锁) 离开临界区后释放锁
k_mutex_lock_timeout() 带超时的加锁 限时等待获取锁
k_mutex_get_count() 获取锁计数 调试和状态检查
k_mutex_get_owner() 获取当前锁所有者 调试和死锁分析
K_MUTEX_DEFINE() 静态定义互斥锁 编译时定义(推荐)

1.2 互斥锁的核心概念

互斥锁是一个二进制信号量,具有以下关键特性:

cpp 复制代码
互斥锁状态图:
    未锁定 ───[线程A加锁]──→ 锁定(所有者:线程A)
        ↑                       |
        |                    [线程A解锁]
        +───────────────────────+

关键特性:

  • 所有权 :锁被哪个线程获取,就必须由同一个线程释放

  • 递归锁定 :Zephyr 互斥锁不支持递归锁定(同一线程多次加锁会导致死锁)

  • 优先级继承 :当启用 CONFIG_PRIORITY_INHERITANCE 时,可防止优先级反转

  • 超时机制:支持带超时的加锁操作

1.3 互斥锁与其他同步机制对比

特性 互斥锁 (k_mutex) 信号量 (k_sem) 自旋锁 (k_spinlock)
所有权 (必须由获取者释放) 无(任何线程可释放) 有(需同一CPU核释放)
递归锁定 不支持 支持(计数信号量) 不支持
优先级反转 可预防(优先级继承) 可能发生 无(禁用抢占)
适用场景 长时间临界区、复杂资源 同步、资源计数 极短临界区、中断上下文
性能开销 中等(可能线程切换) 极低(忙等待)
中断中使用 不能 可以(k_sem_give() 可以(需特殊处理)

2 核心函数与使用

2.1 初始化互斥锁

1) 静态初始化(推荐)

cpp 复制代码
#include <zephyr/kernel.h>

/* 静态定义互斥锁 */
K_MUTEX_DEFINE(my_mutex);

void example_static_init(void) {
    printk("互斥锁已静态初始化\n");
}

2) 动态初始化

cpp 复制代码
/* 动态初始化互斥锁 */
void example_dynamic_init(void) {
    struct k_mutex dynamic_mutex;
    
    k_mutex_init(&dynamic_mutex);
    printk("互斥锁已动态初始化\n");
}

2.2 基本加锁与解锁操作

cpp 复制代码
/* 全局共享资源 */
static int shared_counter = 0;
static float shared_data[10];

/* 定义保护这些资源的互斥锁 */
K_MUTEX_DEFINE(data_mutex);

/* 线程A:访问共享资源 */
void thread_a_entry(void *arg1, void *arg2, void *arg3) {
    int ret;
    
    while (1) {
        /* 1. 获取互斥锁(阻塞等待) */
        ret = k_mutex_lock(&data_mutex, K_FOREVER);
        
        if (ret == 0) {
            /* 2. 进入临界区 - 安全访问共享资源 */
            shared_counter++;
            
            /* 模拟一些处理 */
            for (int i = 0; i < 10; i++) {
                shared_data[i] = shared_counter * i;
            }
            
            printk("Thread A: counter = %d\n", shared_counter);
            
            /* 3. 释放互斥锁(必须由同一线程释放) */
            k_mutex_unlock(&data_mutex);
        }
        
        k_sleep(K_MSEC(100));
    }
}

/* 线程B:也访问相同的共享资源 */
void thread_b_entry(void *arg1, void *arg2, void *arg3) {
    int ret;
    
    while (1) {
        /* 尝试获取互斥锁(带超时) */
        ret = k_mutex_lock(&data_mutex, K_MSEC(50));
        
        if (ret == 0) {
            /* 成功获取锁,访问共享资源 */
            shared_counter--;
            
            printk("Thread B: counter = %d\n", shared_counter);
            
            /* 释放锁 */
            k_mutex_unlock(&data_mutex);
        } else if (ret == -EAGAIN) {
            /* 超时,未能获取锁 */
            printk("Thread B: 等待锁超时,执行其他操作\n");
            /* 这里可以执行不需要共享资源的其他任务 */
        }
        
        k_sleep(K_MSEC(150));
    }
}

2.3 带超时的加锁操作

cpp 复制代码
int safe_mutex_lock(struct k_mutex *mutex, int timeout_ms, 
                    const char *caller) {
    int ret;
    
    if (timeout_ms == 0) {
        /* 非阻塞尝试 */
        ret = k_mutex_lock(mutex, K_NO_WAIT);
    } else if (timeout_ms < 0) {
        /* 永久等待 */
        ret = k_mutex_lock(mutex, K_FOREVER);
    } else {
        /* 限时等待 */
        ret = k_mutex_lock(mutex, K_MSEC(timeout_ms));
    }
    
    switch (ret) {
        case 0:
            printk("%s: 成功获取锁\n", caller);
            return 0;
        case -EAGAIN:
            printk("%s: 锁被占用,超时\n", caller);
            return -ETIMEDOUT;
        case -EBUSY:
            printk("%s: 锁忙(非阻塞模式)\n", caller);
            return -EBUSY;
        default:
            printk("%s: 加锁错误: %d\n", caller, ret);
            return ret;
    }
}

/* 使用示例 */
void critical_operation(void) {
    /* 最多等待100ms获取锁 */
    if (safe_mutex_lock(&data_mutex, 100, "critical_operation") == 0) {
        /* 执行关键操作 */
        perform_critical_work();
        
        /* 释放锁 */
        k_mutex_unlock(&data_mutex);
    }
}

2.4 互斥锁状态查询

cpp 复制代码
/* 监控互斥锁状态 */
void monitor_mutex_status(struct k_mutex *mutex, const char *name) {
    /* 获取锁的所有者 */
    k_tid_t owner = k_mutex_get_owner(mutex);
    
    if (owner != NULL) {
        /* 获取锁计数(对于互斥锁通常是0或1) */
        int count = k_mutex_get_count(mutex);
        
        printk("[%s] 状态: 锁定中\n", name);
        printk("  所有者: %p\n", owner);
        printk("  锁定计数: %d\n", count);
        
        /* 可以进一步获取线程信息 */
        #ifdef CONFIG_THREAD_MONITOR
        printk("  所有者名称: %s\n", k_thread_name_get(owner));
        #endif
    } else {
        printk("[%s] 状态: 未锁定\n", name);
    }
}

/* 死锁检测辅助函数 */
void check_for_deadlock(struct k_mutex *mutex1, struct k_mutex *mutex2) {
    k_tid_t owner1 = k_mutex_get_owner(mutex1);
    k_tid_t owner2 = k_mutex_get_owner(mutex2);
    
    if (owner1 != NULL && owner2 != NULL && owner1 == owner2) {
        printk("警告: 潜在的死锁风险!\n");
        printk("  线程 %p 持有多个互斥锁\n", owner1);
        
        /* 这里可以添加更复杂的死锁检测逻辑 */
    }
}

3 完整应用示例

3.1 保护共享硬件资源

cpp 复制代码
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/i2c.h>

/* I2C设备通常需要互斥锁保护,因为多个线程可能同时访问 */
K_MUTEX_DEFINE(i2c_bus_mutex);

/* 共享的I2C设备 */
const struct device *i2c_dev = DEVICE_DT_GET(DT_NODELABEL(i2c0));

/* 线程安全的I2C读取函数 */
int thread_safe_i2c_read(uint8_t dev_addr, uint8_t reg_addr, 
                         uint8_t *data, size_t len) {
    int ret;
    
    /* 1. 获取I2C总线锁 */
    ret = k_mutex_lock(&i2c_bus_mutex, K_MSEC(100));
    if (ret != 0) {
        printk("获取I2C总线锁超时\n");
        return -ETIMEDOUT;
    }
    
    /* 2. 执行I2C操作(临界区)*/
    struct i2c_msg msgs[2] = {
        /* 发送寄存器地址 */
        {
            .buf = &reg_addr,
            .len = 1,
            .flags = I2C_MSG_WRITE,
        },
        /* 读取数据 */
        {
            .buf = data,
            .len = len,
            .flags = I2C_MSG_READ | I2C_MSG_STOP,
        }
    };
    
    ret = i2c_transfer(i2c_dev, &msgs[0], 2, dev_addr);
    
    /* 3. 无论成功与否,都必须释放锁 */
    k_mutex_unlock(&i2c_bus_mutex);
    
    return ret;
}

/* 多个传感器线程同时使用I2C总线 */
void temperature_sensor_thread(void) {
    uint8_t temp_data[2];
    
    while (1) {
        /* 线程安全的I2C读取 */
        if (thread_safe_i2c_read(0x48, 0x00, temp_data, 2) == 0) {
            int16_t temp = (temp_data[0] << 8) | temp_data[1];
            printk("温度: %.1f°C\n", temp / 256.0);
        }
        
        k_sleep(K_MSEC(1000));
    }
}

void humidity_sensor_thread(void) {
    uint8_t humi_data[2];
    
    while (1) {
        /* 同样使用线程安全的I2C读取 */
        if (thread_safe_i2c_read(0x49, 0x01, humi_data, 2) == 0) {
            uint16_t humidity = (humi_data[0] << 8) | humi_data[1];
            printk("湿度: %.1f%%\n", humidity / 10.0);
        }
        
        k_sleep(K_MSEC(1500));
    }
}

3.2 复杂数据结构保护

cpp 复制代码
#include <zephyr/kernel.h>
#include <string.h>

/* 需要保护的复杂数据结构 */
struct shared_database {
    struct {
        char name[32];
        uint32_t id;
        float value;
    } records[50];
    
    uint32_t record_count;
    uint32_t last_update;
};

/* 全局共享数据库实例和对应的互斥锁 */
static struct shared_database app_database;
K_MUTEX_DEFINE(database_mutex);

/* 线程安全的数据库操作 */
int database_add_record(const char *name, uint32_t id, float value) {
    int ret;
    
    /* 获取数据库锁 */
    ret = k_mutex_lock(&database_mutex, K_MSEC(200));
    if (ret != 0) {
        return -ETIMEDOUT;
    }
    
    /* 临界区开始 */
    if (app_database.record_count >= 50) {
        k_mutex_unlock(&database_mutex);
        return -ENOSPC;  /* 数据库已满 */
    }
    
    /* 添加新记录 */
    struct shared_database *db = &app_database;
    uint32_t index = db->record_count;
    
    strncpy(db->records[index].name, name, 
            sizeof(db->records[index].name) - 1);
    db->records[index].name[sizeof(db->records[index].name) - 1] = '\0';
    
    db->records[index].id = id;
    db->records[index].value = value;
    
    db->record_count++;
    db->last_update = k_cycle_get_32();
    
    /* 临界区结束,释放锁 */
    k_mutex_unlock(&database_mutex);
    
    printk("添加记录: %s (ID: %u)\n", name, id);
    return 0;
}

/* 线程安全的数据库查询 */
int database_find_record(uint32_t id, char *name_buf, size_t buf_size,
                         float *value) {
    int ret;
    int found = -ENOENT;  /* 默认未找到 */
    
    ret = k_mutex_lock(&database_mutex, K_MSEC(100));
    if (ret != 0) {
        return -ETIMEDOUT;
    }
    
    /* 在数据库中查找 */
    for (uint32_t i = 0; i < app_database.record_count; i++) {
        if (app_database.records[i].id == id) {
            /* 找到记录,复制数据 */
            if (name_buf != NULL && buf_size > 0) {
                strncpy(name_buf, app_database.records[i].name, buf_size - 1);
                name_buf[buf_size - 1] = '\0';
            }
            
            if (value != NULL) {
                *value = app_database.records[i].value;
            }
            
            found = 0;  /* 成功找到 */
            break;
        }
    }
    
    k_mutex_unlock(&database_mutex);
    return found;
}

/* 数据库维护线程 */
void database_maintenance_thread(void) {
    while (1) {
        /* 定期清理旧记录 */
        k_mutex_lock(&database_mutex, K_FOREVER);
        
        uint32_t old_count = app_database.record_count;
        
        /* 模拟清理逻辑(这里简化处理) */
        if (app_database.record_count > 40) {
            /* 删除前10条记录(模拟) */
            for (int i = 0; i < app_database.record_count - 10; i++) {
                app_database.records[i] = app_database.records[i + 10];
            }
            app_database.record_count -= 10;
            
            printk("数据库维护: 清理了10条记录\n");
        }
        
        k_mutex_unlock(&database_mutex);
        
        k_sleep(K_SECONDS(30));  /* 每30秒维护一次 */
    }
}

3.3 避免死锁的模式

cpp 复制代码
/* 死锁避免:固定锁获取顺序 */
#define LOCK_ORDER_FIRST   0
#define LOCK_ORDER_SECOND  1
#define LOCK_ORDER_THIRD   2

K_MUTEX_DEFINE(mutex_a);
K_MUTEX_DEFINE(mutex_b);
K_MUTEX_DEFINE(mutex_c);

/* 按照固定顺序获取锁的函数 */
int acquire_mutexes_in_order(int order_mask, k_timeout_t timeout) {
    int ret;
    
    /* 总是按照A→B→C的顺序获取锁 */
    if (order_mask & (1 << LOCK_ORDER_FIRST)) {
        ret = k_mutex_lock(&mutex_a, timeout);
        if (ret != 0) {
            return ret;  /* 获取失败 */
        }
    }
    
    if (order_mask & (1 << LOCK_ORDER_SECOND)) {
        ret = k_mutex_lock(&mutex_b, timeout);
        if (ret != 0) {
            /* 获取mutex_b失败,释放已获取的mutex_a */
            if (order_mask & (1 << LOCK_ORDER_FIRST)) {
                k_mutex_unlock(&mutex_a);
            }
            return ret;
        }
    }
    
    if (order_mask & (1 << LOCK_ORDER_THIRD)) {
        ret = k_mutex_lock(&mutex_c, timeout);
        if (ret != 0) {
            /* 获取mutex_c失败,释放已获取的所有锁 */
            if (order_mask & (1 << LOCK_ORDER_SECOND)) {
                k_mutex_unlock(&mutex_b);
            }
            if (order_mask & (1 << LOCK_ORDER_FIRST)) {
                k_mutex_unlock(&mutex_a);
            }
            return ret;
        }
    }
    
    return 0;  /* 成功获取所有请求的锁 */
}

/* 按照相反顺序释放锁 */
void release_mutexes_in_reverse_order(int order_mask) {
    if (order_mask & (1 << LOCK_ORDER_THIRD)) {
        k_mutex_unlock(&mutex_c);
    }
    
    if (order_mask & (1 << LOCK_ORDER_SECOND)) {
        k_mutex_unlock(&mutex_b);
    }
    
    if (order_mask & (1 << LOCK_ORDER_FIRST)) {
        k_mutex_unlock(&mutex_a);
    }
}

/* 使用示例 */
void safe_critical_operation(void) {
    /* 需要获取mutex_a和mutex_c */
    int needed_locks = (1 << LOCK_ORDER_FIRST) | (1 << LOCK_ORDER_THIRD);
    
    if (acquire_mutexes_in_order(needed_locks, K_MSEC(100)) == 0) {
        /* 执行需要mutex_a和mutex_c的操作 */
        perform_operation();
        
        /* 释放锁 */
        release_mutexes_in_reverse_order(needed_locks);
    } else {
        printk("获取锁失败\n");
    }
}

3.4 调试与性能分析

cpp 复制代码
/* 互斥锁性能监控 */
struct mutex_stats {
    uint32_t lock_count;
    uint32_t unlock_count;
    uint32_t timeout_count;
    uint64_t total_wait_time;
    uint64_t max_wait_time;
};

static struct mutex_stats mutex_stats;

/* 增强的加锁函数,带统计 */
int instrumented_mutex_lock(struct k_mutex *mutex, k_timeout_t timeout,
                            const char *location) {
    uint32_t start_cycles = k_cycle_get_32();
    int ret = k_mutex_lock(mutex, timeout);
    uint32_t end_cycles = k_cycle_get_32();
    
    mutex_stats.lock_count++;
    
    if (ret == 0) {
        uint32_t wait_cycles = end_cycles - start_cycles;
        uint32_t wait_us = k_cyc_to_us_near32(wait_cycles);
        
        mutex_stats.total_wait_time += wait_us;
        
        if (wait_us > mutex_stats.max_wait_time) {
            mutex_stats.max_wait_time = wait_us;
            
            if (wait_us > 1000) {  /* 超过1ms的等待 */
                printk("长等待警告: %s 等待 %u us\n", location, wait_us);
            }
        }
    } else if (ret == -EAGAIN) {
        mutex_stats.timeout_count++;
        printk("锁超时: %s\n", location);
    }
    
    return ret;
}

/* 定期报告统计 */
void report_mutex_stats(void) {
    static int64_t last_report = 0;
    int64_t now = k_uptime_get();
    
    if (now - last_report > 10000) {  /* 每10秒 */
        printk("=== 互斥锁统计 ===\n");
        printk("加锁次数: %u\n", mutex_stats.lock_count);
        printk("解锁次数: %u\n", mutex_stats.unlock_count);
        printk("超时次数: %u\n", mutex_stats.timeout_count);
        
        if (mutex_stats.lock_count > 0) {
            uint32_t avg_wait = mutex_stats.total_wait_time / mutex_stats.lock_count;
            printk("平均等待: %u us\n", avg_wait);
            printk("最大等待: %llu us\n", mutex_stats.max_wait_time);
        }
        
        last_report = now;
    }
}

3.5 错误处理模式

cpp 复制代码
/* 互斥锁错误处理宏 */
#define MUTEX_LOCK_GUARD(mutex, timeout) \
    for (int _mutex_ret = k_mutex_lock(mutex, timeout); \
         _mutex_ret == 0; \
         k_mutex_unlock(mutex), _mutex_ret = -1)

#define MUTEX_LOCK_CHECK(mutex, timeout, on_error) \
    do { \
        int _ret = k_mutex_lock(mutex, timeout); \
        if (_ret != 0) { \
            on_error; \
        } \
    } while (0)

/* 使用示例 */
void example_with_error_handling(void) {
    /* 模式1:使用守卫宏(自动释放) */
    MUTEX_LOCK_GUARD(&data_mutex, K_MSEC(100)) {
        /* 这里可以安全访问共享数据 */
        access_shared_data();
        /* 离开作用域时自动解锁 */
    }
    
    /* 模式2:带错误检查 */
    MUTEX_LOCK_CHECK(&data_mutex, K_MSEC(50), {
        printk("无法获取锁,跳过操作\n");
        return;
    });
    
    /* 手动解锁 */
    k_mutex_unlock(&data_mutex);
}

/* 健壮的互斥锁包装函数 */
struct mutex_handle {
    struct k_mutex *mutex;
    bool locked;
};

struct mutex_handle mutex_lock_auto(struct k_mutex *mutex, k_timeout_t timeout) {
    struct mutex_handle handle = {
        .mutex = mutex,
        .locked = (k_mutex_lock(mutex, timeout) == 0)
    };
    return handle;
}

void mutex_unlock_auto(struct mutex_handle *handle) {
    if (handle->locked) {
        k_mutex_unlock(handle->mutex);
        handle->locked = false;
    }
}

/* 使用示例(类似C++的RAII模式) */
void raii_style_example(void) {
    struct mutex_handle handle = mutex_lock_auto(&data_mutex, K_MSEC(100));
    
    if (handle.locked) {
        /* 安全操作 */
        process_data();
        
        /* 自动释放(通过函数调用) */
        mutex_unlock_auto(&handle);
    }
}

3.6 调试函数

cpp 复制代码
/* 互斥锁调试信息转储 */
void dump_mutex_debug_info(struct k_mutex *mutex) {
    #ifdef CONFIG_DEBUG_MUTEX
    printk("=== 互斥锁调试信息 ===\n");
    printk("地址: %p\n", mutex);
    
    k_tid_t owner = k_mutex_get_owner(mutex);
    printk("所有者: %p\n", owner);
    
    if (owner != NULL) {
        #ifdef CONFIG_THREAD_MONITOR
        printk("所有者名称: %s\n", k_thread_name_get(owner));
        printk("所有者优先级: %d\n", k_thread_priority_get(owner));
        #endif
    }
    
    printk("锁计数: %d\n", k_mutex_get_count(mutex));
    
    /* 检查等待队列 */
    #ifdef CONFIG_WAITQ_MAX_MONITOR_COUNT
    printk("等待线程数: %zu\n", 
           k_mutex_get_wait_count(mutex));  /* 假设有该函数 */
    #endif
    #endif
}

/* 死锁检测(简化版) */
void check_for_potential_deadlocks(void) {
    #ifdef CONFIG_DEBUG_MUTEX
    /* 这里可以实现更复杂的死锁检测逻辑 */
    printk("死锁检测运行...\n");
    
    /* 示例:检查所有互斥锁的所有者 */
    /* 实际实现需要维护系统所有互斥锁的列表 */
    #endif
}

4 应用总结

4.1 常见陷阱与解决方案

陷阱 后果 解决方案
忘记解锁 死锁、资源永久不可用 1. 使用守卫模式 2. 代码审查 3. 静态分析工具
递归加锁 死锁(Zephyr不支持递归锁) 1. 避免同一线程多次加锁 2. 使用递归计数器检查
锁顺序不一致 死锁(线程A等B,B等A) 1. 固定锁获取顺序 2. 使用死锁检测算法
过长的临界区 性能下降、响应延迟 1. 最小化临界区代码 2. 拆分大锁为多个小锁
中断中加锁 系统挂起(中断不能阻塞) 1. 使用自旋锁保护中断共享数据 2. 将工作推迟到线程中处理

4.2 配置

bash 复制代码
# 基本配置(通常默认已启用)
CONFIG_MUTEX=y

# 调试支持
CONFIG_DEBUG_MUTEX=y           # 互斥锁调试
CONFIG_ASSERT=y                # 启用断言
CONFIG_THREAD_MONITOR=y        # 线程监控

# 高级特性
CONFIG_PRIORITY_INHERITANCE=y  # 优先级继承
CONFIG_PRIORITY_INHERITANCE_CHAIN_LIMIT=3  # 继承链限制

# 性能监控
CONFIG_KERNEL_COUNTERS=y       # 内核计数器

4.3 特性总结

Zephyr 的互斥锁 (k_mutex) 是保护共享资源、防止数据竞争的关键机制。正确使用互斥锁需要注意:

1) 核心要点:

  1. 所有权明确:谁加锁,谁解锁

  2. 临界区最小化:锁内代码尽可能少,执行时间尽可能短

  3. 避免死锁:固定锁获取顺序,使用超时机制

  4. 错误处理:始终检查加锁返回值,准备超时处理

2) 使用建议:

  1. 保护共享数据:当多个线程访问共享变量或数据结构时

  2. 保护硬件资源:当多个线程访问同一外设时(如I2C、SPI总线)

  3. 协调复杂操作:需要确保一系列操作原子性时

3) 选择时机:

  • 用互斥锁:需要所有权、保护长时间操作、复杂资源

  • 用信号量:简单同步、资源计数、生产者-消费者

  • 用自旋锁:极短临界区、中断上下文

通过合理使用互斥锁,可以在 Zephyr 多线程应用中构建安全、高效的共享资源访问机制。记住:锁不是越多越好,也不是越少越好,而是刚刚好。 正确的锁设计需要在安全性和性能之间找到平衡。

相关推荐
fitpolo2 天前
蓝牙低功耗基3-蓝牙低功耗中的数据交4
zephyr
mftang6 天前
Zephyr RTOS 中timing 相关函数功能介绍
时间管理·zephyr rtos
嵌入式学习和实践17 天前
Zephyr 实时系统下 W25Q128 + LittleFS 文件系统实战指南
zephyr·lfs文件系统·w25q128
mftang17 天前
Zephyr RTOS 下 BLE 主动扫描和被动扫描详解
被动扫描·蓝牙协议栈·zephyr·主动扫描
mftang17 天前
Zephyr RTOS 中用于同步多路复用 I/O 的核心机制k_poll 相关函数用法
zephyr rtos·k_poll
mftang18 天前
Zephyr RTOS中bt_conn_le_create 函数用法详细介绍
zephyr·ble central
mftang18 天前
Zephyr RTOS 中k_cpu_idle 函数功能介绍
zephyr rtos·k_cpu_idle
mftang1 个月前
Zephyr RTOS 下 bt_le_scan_start 函数详解
被动扫描·zephyr rtos·主动扫描
代码中介商1 个月前
Linux多线程编程完全指南(下):线程同步与互斥锁
linux·redis·线程·互斥锁