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;
相关推荐
aspirestro三水哥2 天前
8.5CPU隔离与亲和性
rtos·xenomai
帅得不敢出门3 天前
MacOS安装VSCode在QEMU上模拟跑FreeRtos
ide·vscode·macos·freertos·rtos
liu_endong3 天前
RTOS基于7840——任务创建、启动、切换、删除
mcu·rtos·杰发科技·autochips·车规芯片
香水5只用六神6 天前
【RTOS快速入门】05_动态_静态创建任务(2)
c语言·stm32·单片机·嵌入式硬件·freertos·rtos·嵌入式软件
香水5只用六神6 天前
【RTOS快速入门】06_任务状态理论讲解(1)
c语言·stm32·单片机·嵌入式硬件·freertos·rtos·嵌入式软件
香水5只用六神7 天前
【RTOS快速入门】07_同步互斥与通信概述
单片机·嵌入式硬件·学习·操作系统·freertos·rtos·嵌入式软件
香水5只用六神7 天前
【RTOS快速入门】05_动态_静态创建任务(1)
c语言·开发语言·单片机·嵌入式硬件·freertos·rtos·嵌入式软件
混分巨兽龙某某2 个月前
基于STM32的嵌入式操作系统RT-Thread移植教学(HAL库版本)
stm32·嵌入式硬件·rt-thread·rtos
aspirestro三水哥2 个月前
7.2实时进程如何打印输出
rtos·xenomai
aspirestro三水哥2 个月前
6.7RTIPC之XDDP实例分析
rtos·xenomai