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三水哥1 天前
6.4非POSIXskin进程间通信
rtos·xenomai
鸿蒙小白龙4 天前
OpenHarmony轻量系统(Hi3861)RTOS API开发详解
openharmony·rtos·liteos·轻量系统
无聊到发博客的菜鸟13 天前
STM32 手册寄存器属性
stm32·单片机·嵌入式·rtos·寄存器
aspirestro三水哥13 天前
5.3RTDM用户层驱动
rtos·xenomai
无聊到发博客的菜鸟13 天前
STM32 RTC时钟不准的问题
stm32·嵌入式·rtc·rtos
aspirestro三水哥15 天前
4.7POSIX进程与线程实例
rtos·xenomai
无聊到发博客的菜鸟15 天前
使用STM32对SD卡进行性能测试
stm32·单片机·rtos·sd卡·fatfs
切糕师学AI18 天前
Azure RTOS ThreadX 简介
microsoft·嵌入式·azure·rtos
切糕师学AI21 天前
FreeRTOS是什么?
嵌入式·rtos