qq_38072967 2023-10-18 16:03 采纳率: 0%
浏览 11

使用RTAI实时信号量进行实时线程与非实时线程同步时,非实时线程拿不到实时信号量

问题遇到的现象和发生背景

使用RTAI实时信号量进行实时线程与非实时线程同步时,非实时线程拿不到实时信号量

操作环境、软件版本等信息

RTAI LXRT模块

尝试过的解决方法

编写测试用例,创建非实时线程和实时任务,测试实时信号量同步效果

#include <stdio.h>
#include <pthread.h>
#include <rtai_sched.h>
#include <rtai_sem.h>



// 定义全局的信号量变量
    SEM *sem = NULL; 
    unsigned long sem_name = 10; // 信号量的名称
#if 0
// 非实时线程 线程1执行的函数
void* thread1_func(void* arg) {
    printf("Thread 1 executing...\n");
    if (sem != NULL) 
    {
        printf("Thread 1\n");
        //printf("rt_sem_wait(sem):%d\n",rt_sem_wait(sem));
        // 等待信号量
        if (rt_sem_wait(sem) == 0) {
            printf("Thread 1 acquired the semaphore.\n");
            // 释放信号量
            rt_sem_signal(sem);
        } else {
            printf("Thread 1 failed to acquire the semaphore.\n");
        }
    }
    printf("Thread 1 exiting...\n");
    return NULL;
}
#endif
void* thread1_func(void* arg)
{
    int tick = 3;
    //RT_TASK* task = rt_task_shadow(nam2num("rtai"), "nonrt_task", SCHED_FIFO, 0);
    mlockall(MCL_CURRENT | MCL_FUTURE);

    printf("Non-realtime thread executing...\n");

    if (sem != NULL) {
        // 等待信号量
        if (rt_sem_wait(sem) == 0) {
            printf("Non-realtime thread acquired the semaphore.\n");
            // 释放信号量
            rt_sem_signal(sem);
        } else {
            printf("Non-realtime thread failed to acquire the semaphore.\n");
        }
    }

    printf("Non-realtime thread exiting...\n");
    //rt_task_delete(task);
    return NULL;
}
// 实时线程 线程2执行的函数
void* thread2_func(void* arg)
{
    int tick =  3;
    RT_TASK* task = rt_task_init_schmod(nam2num("rtai"), 0, 0, 0, SCHED_FIFO, 255);
    mlockall(MCL_CURRENT | MCL_FUTURE);
    RTIME interval = nano2count(tick * 1000);
    RTIME expected = rt_get_time() + 100 * interval;
    rt_task_make_periodic(task, expected, interval);
    rt_make_hard_real_time();
    
    printf("Thread 2 executing...\n");
    if (sem != NULL) 
    {
        // 等待信号量
        if (rt_sem_wait(sem) == 0) {
            printf("Thread 2 acquired the semaphore.\n");
            // 释放信号量
            rt_sem_signal(sem);
        } else {
            printf("Thread 2 failed to acquire the semaphore.\n");
        }
    }
    printf("Thread 2 exiting...\n");
    rt_task_delete(task);
    return NULL;
}
int main() {
    sem = rt_sem_init(sem_name, 1);
    // 打印初始信号量值
    printf("Initial semaphore opaque: %p\n", sem);
    //printf("Initial semaphore opaque: %d\n", sem->opaque);
    printf("sem_name: %lu\n", sem_name);
    
    // 创建线程1
    pthread_t thread1;
    if (pthread_create(&thread1, NULL, thread1_func, NULL) != 0) {
        printf("Failed to create thread 1.\n");
        return 1;
    }
    pthread_t thread2;
    if (pthread_create(&thread2, NULL, thread2_func, NULL) != 0) {
        printf("Failed to create thread 2.\n");
        return 1;
    }
    
    usleep(1000000);
    
    #if 1
    // 等待线程1完成
    if (pthread_join(thread1, NULL) != 0) {
        printf("Failed to join thread 1.\n");
        return 1;
    }


    // 等待线程2完成
    if (pthread_join(thread2, NULL) != 0) {
        printf("Failed to join thread 2.\n");
        return 1;
    }
    #endif
    // 删除信号量
    if (sem != NULL) 
    {
         printf("rt_sem_delete...\n");
         rt_sem_delete(sem);
    }
    return 0;
}

我想要达到的结果

RTAI环境下,使用实时信号量实现实时线程与非实时线程的同步

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-10-19 00:20
    关注

    【以下回答由 GPT 生成】

    在使用RTAI实时信号量进行实时线程与非实时线程同步时,非实时线程无法获取实时信号量的问题可能是由于以下原因导致的:

    1. 实时信号量初始化的步骤有误。
    2. 代码中存在竞争条件导致信号量被非实时线程获得,而不是实时线程。
    3. 非实时线程没有得到足够的CPU时间,在实时任务的优先级高于非实时线程的情况下,非实时线程可能会被阻塞。

    为了解决这个问题,可以尝试以下步骤:

    1. 确保正确初始化实时信号量。在代码示例中,使用rt_typed_sem_init初始化实时信号量。请检查sem_name的值是否正确,并检查实时信号量的类型是否正确。

    2. 避免竞争条件,确保实时线程先获得信号量。可以通过修改代码,在非实时线程的执行之前,让实时线程先获得信号量,然后在实时线程结束之后,释放信号量供非实时线程使用。可以使用rt_sem_waitrt_sem_signal来实现。

    以下是修改后的代码示例:

    #include <stdio.h>
    #include <pthread.h>
    #include <rtai_sched.h>
    #include <rtai_sem.h>
    
    SEM *sem = NULL;
    unsigned long sem_name = 10;
    
    void* thread1_func(void* arg) {
        printf("Thread 1 executing...\n");
        if (sem != NULL) {
            printf("Thread 1\n");
            if (rt_sem_wait(sem) == 0) {
                printf("Thread 1 acquired the semaphore.\n");
                // 在实时线程结束之后释放信号量
                pthread_join(*(pthread_t*)arg, NULL);
                rt_sem_signal(sem);
            } else {
                printf("Thread 1 failed to acquire the semaphore.\n");
            }
        }
        printf("Thread 1 exiting...\n");
        return NULL;
    }
    
    int main() {
        pthread_t thread1, thread2;
    
        // 创建实时线程先获得信号量
        pthread_create(&thread2, NULL, thread2_func, &thread1);
        pthread_create(&thread1, NULL, thread1_func, &thread2);
    
        // 创建实时信号量
        sem = rt_typed_sem_init(nam2num("rtai"), sem_name, 1, BIN_SEM);
    
        // 实时线程开始执行,获取信号量
        pthread_join(thread2, NULL);
    
        // 等待非实时线程执行完毕
        pthread_join(thread1, NULL);
    
        // 删除实时信号量
        rt_sem_delete(sem);
    
        return 0;
    }
    

    这样,就确保了在非实时线程执行之前,实时线程能够获得信号量,并在实时线程结束之后释放信号量供非实时线程使用。

    1. 如果非实时线程没有得到足够的CPU时间,可以尝试提高非实时线程的优先级。可以使用pthread_setschedparam函数来设置非实时线程的优先级。

    以下是修改后的代码示例,展示如何设置非实时线程的优先级:

    #include <stdio.h>
    #include <pthread.h>
    #include <sched.h>
    #include <rtai_sched.h>
    #include <rtai_sem.h>
    
    SEM *sem = NULL;
    unsigned long sem_name = 10;
    
    void* thread1_func(void* arg) {
        printf("Thread 1 executing...\n");
        if (sem != NULL) {
            printf("Thread 1\n");
            if (rt_sem_wait(sem) == 0) {
                printf("Thread 1 acquired the semaphore.\n");
                rt_sem_signal(sem);
            } else {
                printf("Thread 1 failed to acquire the semaphore.\n");
            }
        }
        printf("Thread 1 exiting...\n");
        return NULL;
    }
    
    int main() {
        // 创建非实时线程
        pthread_t thread1;
        pthread_attr_t attr;
        struct sched_param param;
    
        pthread_attr_init(&attr);
        pthread_attr_getschedparam(&attr, &param);
        // 设置非实时线程的优先级较高
        param.sched_priority = sched_get_priority_max(SCHED_OTHER);
        pthread_attr_setschedparam(&attr, &param);
    
        pthread_create(&thread1, &attr, thread1_func, NULL);
    
        // 创建实时任务,此处省略了实时线程的相关代码
    
        // 创建实时信号量
        sem = rt_typed_sem_init(nam2num("rtai"), sem_name, 1, BIN_SEM);
    
        // 等待非实时线程执行完毕
        pthread_join(thread1, NULL);
    
        // 删除实时信号量
        rt_sem_delete(sem);
    
        return 0;
    }
    

    通过设置非实时线程的优先级较高,可以确保非实时线程在实时任务之后得到足够的CPU时间。

    以上是对于问题的解决方案的建议,希望对您有所帮助。如果以上解决方案并未解决问题,那么可能需要深入研究RTAI实时信号量的工作原理和使用方法,或者咨询RTAI专家以获取更准确的支持。


    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 创建了问题 10月18日

悬赏问题

  • ¥15 excel 上下按钮 显示行
  • ¥20 搭建三相栅极电路后高侧浮动地VS存在电容特性
  • ¥20 云卓h12pro 数传问题
  • ¥20 请问有人知道怎么用工艺库里面的sdb文件通过virtuoso导出来library里面每个cell的symbol吗?
  • ¥20 海思 nnie 编译 报错
  • ¥50 决策面并仿真,要求有仿真结果图
  • ¥15 关于路由器的路由协议配置
  • ¥15 springboot接入微信支付SDK
  • ¥50 大区域的遥感影像匹配 怎么做啊
  • ¥15 求解答:pytorch跑yolov8神经网络受挫