6.2POSIX线程间通信

6.2 POSIX线程间通信

使用 Xenomai 的 POSIX skin创建的POSIX线程,在同一进程内共享相同的地址空间,线程间直接共享同步对象,例如信号量,互斥锁,条件变量等等。

但是,Xenomai 不支持 POSIX 标准中的静态初始化。

1. POSIX 标准中的静态初始化

在 POSIX 标准里,为了方便静态互斥锁(mutex)和条件变量(condition variables)的初始化,定义了 PTHREAD_COND_INITIALIZER 和 PTHREAD_MUTEX_INITIALIZER 这两个初始化器。借助这两个初始化器,开发者能够在声明静态互斥锁和条件变量时直接完成初始化,示例如下:

复制代码
#include <pthread.h>

// 静态初始化互斥锁
pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER;
// 静态初始化条件变量
pthread_cond_t my_cond = PTHREAD_COND_INITIALIZER;

这种静态初始化方式简洁高效,能在程序启动时就完成对象的初始化,避免了额外的函数调用开销。

2. Xenomai POSIX 层的特殊需求

然而,Xenomai POSIX 层由于其自身的特性,需要通过系统调用来初始化互斥锁和条件变量。这意味着上述 POSIX 标准的静态初始化方式在 Xenomai 环境下无法正常工作,因为 PTHREAD_COND_INITIALIZER 和 PTHREAD_MUTEX_INITIALIZER 无法完成 Xenomai 所需的系统调用初始化过程。

面对这个问题,有两种解决方案可供选择,最终Xenomai选择方案二。

  • 方案一: 首次调用其他服务时初始化对象

第一种方案是在首次调用与互斥锁或条件变量相关的其他服务(如 pthread_mutex_lock 或 pthread_cond_wait)时,触发对象的初始化操作。但这种方案存在明显的缺陷。以 pthread_mutex_lock 为例,如果在该函数内部调用初始化例程,会引入额外的不确定性。因为初始化过程可能涉及系统调用,这会增加函数执行时间的不可预测性,破坏了用户对 pthread_mutex_lock 这类服务确定性的预期。在实时系统中,这种不确定性是非常致命的,可能会导致系统性能下降甚至出现错误。

  • 方案二:要求用户调用初始化服务

第二种方案是要求用户主动调用 pthread_mutex_init 和 pthread_cond_init 函数来完成互斥锁和条件变量的初始化。这种方案的优点在于,用户可以在程序执行的非关键时期进行初始化操作,避免了在关键路径上引入额外的开销和不确定性。虽然这增加了用户的编程负担,但能保证系统的实时性和确定性。

综上,在使用 Xenomai POSIX 层的互斥锁和条件变量时,开发者需要仔细检查代码中所有使用静态初始化器的地方,并将其替换为在非关键时期调用 pthread_mutex_init 和 pthread_cond_init 函数。示例如下:

复制代码
#include <pthread.h>

// 声明互斥锁和条件变量
pthread_mutex_t my_mutex;
pthread_cond_t my_cond;

int main() {
    // 在非关键时期初始化互斥锁
    if (pthread_mutex_init(&my_mutex, NULL) != 0) {
        // 处理初始化失败的情况
    }

    // 在非关键时期初始化条件变量
    if (pthread_cond_init(&my_cond, NULL) != 0) {
        // 处理初始化失败的情况
    }

    // 后续正常使用互斥锁和条件变量
    // ...

    // 程序结束时销毁互斥锁和条件变量
    pthread_mutex_destroy(&my_mutex);
    pthread_cond_destroy(&my_cond);

    return 0;
}

通过这种方式,可以确保在 Xenomai 环境下正确使用互斥锁和条件变量,同时保证系统的实时性和确定性。

3. Xenomai 实例

  • 互斥锁 mutex :testsuite/clocktest/clocktest.c

    root@xeno-demo:~# clocktest
    == Testing built-in CLOCK_REALTIME (0)
    CPU ToD offset [us] ToD drift [us/s] warps max delta [us]


    复制代码
    0                  1.1           -0.024          0            0.0
    1                  1.2           -0.016          0            0.0
    2                  1.2            0.009          0            0.0
    3                  1.3           -0.002          0            0.0
  • 互斥量和条件变量:demo/posix/cyclictest/cyclictest.c

为什么使用了静态初始化?

复制代码
static pthread_cond_t refresh_on_max_cond = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t refresh_on_max_lock = PTHREAD_MUTEX_INITIALIZER;

static pthread_mutex_t break_thread_id_lock = PTHREAD_MUTEX_INITIALIZER;
相关推荐
W.W.H.2 天前
优先级反转问题(含解决案例)
互斥锁·rtos·互斥量·实时系统·优先级反转·优先级继承
.普通人5 天前
freertos源码解析(里面的源码来源于另一个博主,我这里只是讲一下我自己的理解)
操作系统·rtos
dqsh068 天前
振兴中华之threadX RTOS移植到stm32用stm32cubeMX 保姆级教程
stm32·单片机·嵌入式硬件·rtos·threadx
Truffle7电子11 天前
STM32理论 —— FreeRTOS:中断管理、列表
stm32·单片机·嵌入式硬件·rtos
Truffle7电子12 天前
STM32理论 —— FreeRTOS:任务
stm32·嵌入式·rtos
大熊背16 天前
ISP离线模式应用(二)-如何利用 ISP 离线模式 加速 3DNR 收敛
linux·算法·rtos·isp pipeline·3dnr
aspirestro三水哥17 天前
9.3工欲善其事必先利其器
rtos·xenomai
逆小舟20 天前
【SWM320】FreeRTOS搭建工程——1、框架学习
嵌入式·c·rtos
aspirestro三水哥20 天前
9.4贡献自己的第一个patch
rtos·xenomai
大志出奇迹20 天前
FreeRTOS中创建任务的顺序是否会影响任务运行的顺序?【面试重点】
c语言·rtos