0

我对 RTOS 编程相当陌生,并且在使用互斥锁时遇到了一些优先级问题。

我确定了以下优先事项。

#define T_HI_PRIORITY 10
#define T_ME_PRIORITY 50

我希望这段代码运行具有最高优先级的任务“tMePriorityTask”和具有中等优先级的“tHiPriorityTask”。“tLoPriorityTask”已被注释,因此现在不应运行。

#include <stdio.h>
#include "main.h"
#include "vxWorks.h"
#include "semLib.h"
#include "taskLib.h"

SEM_ID semMutex;    // named semaphore object

char alphabet[27];  // memory resource to have exclusive access

void tHiPriorityTask (void)
{
   int i;

    // enter critical region - any other tasks wanting access to alphabet[] should
    // wait for available semaphore
    semTake (semMutex, WAIT_FOREVER);

   // write alphabet to global array
    for (i= 0; i < 26; i++)
        alphabet[i] = 'A' + i;

    alphabet[i] = '\0';

    printf("High priority.\n-Counting alphabet...\n");

    // leave critical region
    semGive (semMutex);
}

void tMePriorityTask (void)
{
    // enter critical region
    semTake (semMutex, WAIT_FOREVER);

    //medium priority task enters
    printf("Medium priority.\n-Just entering...\n");

    // leave critical region
    semGive (semMutex);
}

/*void tLoPriorityTask (void)
{
    // enter critical region
    semTake (semMutex, WAIT_FOREVER);

    // array members guaranteed stable while being read by this task
    printf("Low priority\n");
    printf ("-alphabet= %s ", alphabet);

    // leave critical region
    semGive (semMutex);
}*/

void main (void)
{
    //create binary semaphore which is initially full (available)
    semMutex = semBCreate (SEM_Q_PRIORITY, SEM_FULL);

    // spawn high priority task
    taskSpawn ("hi_priority_task", T_ME_PRIORITY, VX_FP_TASK, 10000, (FUNCPTR) tHiPriorityTask, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    // spawn medium priority task
    taskSpawn ("me_priority_task", T_HI_PRIORITY, VX_FP_TASK, 10000, (FUNCPTR) tMePriorityTask, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    // spawn low priority task
    //taskSpawn ("lo_priority_task", T_LO_PRIORITY, VX_FP_TASK, 10000, (FUNCPTR) tLoPriorityTask, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}

我尝试在生成任务时更改优先级,但这似乎不起作用,至少它不会改变屏幕上的任何内容。我正在使用 VxWorks RTOS。

谢谢你。

4

2 回答 2

0

当您说它不起作用时,您期望什么输出?您正在启动 tHiPriorityTask 并且它立即到达信号量,迫使 tMePriorityTask 等待,即使它具有更高的优先级。基本上,具有更高的优先级并不意味着它可以接管一个锁定的信号量,它只是意味着它更有可能在它自己和它的竞争对手处于“就绪”状态时运行。tMePriorityTask 首先运行的唯一情况是 tHiPriorityTask 在 tryig 到达信号量之前被抢占,我想这不太可能,因为你先启动它,它可能会继续运行第一条指令。

于 2013-08-26T10:24:53.000 回答
0

如果要保证两个线程以特定顺序运行,则必须使用正确的线程同步。只是设置优先级并希望它工作是非常糟糕的设计,你可能会让它工作,但它最终会中断(例如,如果你进行阻塞调用,那么没有什么可以阻止任何其他线程运行。)

这是修改代码以保证 tMePriorityTask 线程在允许运行 tHiPriorityTask 之前运行完成的最简单方法,而不管优先级或您在线程中执行的任何其他操作。

#include <stdio.h>
#include "main.h"
#include "vxWorks.h"
#include "semLib.h"
#include "taskLib.h"

SEM_ID semMutex;    // named semaphore object

char alphabet[27];  // memory resource to have exclusive access

void tHiPriorityTask (void)
{
   int i;

    // enter critical region - any other tasks wanting access to alphabet[] should
    // wait for available semaphore
    semTake (semMutex, WAIT_FOREVER);

   // write alphabet to global array
    for (i= 0; i < 26; i++)
        alphabet[i] = 'A' + i;

    alphabet[i] = '\0';

    printf("High priority.\n-Counting alphabet...\n");

    // leave critical region
    semGive (semMutex);
}

void tMePriorityTask (void)
{
    // enter critical region
    //semTake (semMutex, WAIT_FOREVER);

    //medium priority task enters
    printf("Medium priority.\n-Just entering...\n");

    // leave critical region
    semGive (semMutex);
}

/*void tLoPriorityTask (void)
{
    // enter critical region
    semTake (semMutex, WAIT_FOREVER);

    // array members guaranteed stable while being read by this task
    printf("Low priority\n");
    printf ("-alphabet= %s ", alphabet);

    // leave critical region
    semGive (semMutex);
}*/

void main (void)
{
    //create binary semaphore which is initially full (available)
    semMutex = semBCreate (SEM_Q_PRIORITY, SEM_EMPTY);

    // spawn high priority task
    taskSpawn ("hi_priority_task", T_ME_PRIORITY, VX_FP_TASK, 10000, (FUNCPTR) tHiPriorityTask, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    // spawn medium priority task
    taskSpawn ("me_priority_task", T_HI_PRIORITY, VX_FP_TASK, 10000, (FUNCPTR) tMePriorityTask, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    // spawn low priority task
    //taskSpawn ("lo_priority_task", T_LO_PRIORITY, VX_FP_TASK, 10000, (FUNCPTR) tLoPriorityTask, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}

我所做的只是用 SEM_EMPTY 创建信号量,然后从 tMePriorityTask 中删除 semTake。

这样 tHiPriorityTask 可以以任何优先级运行,并且它将阻塞 semTake 直到 tMePriorityTask 发出 semGive。此外,tMePriorityTask 线程可以执行其他阻塞调用(例如 I/O 调用),并且 tHiPriorityTask 线程在 semGive 之前仍然无法运行。

查看 semBCreate 的 vxworks API 参考并阅读标题为 SYNCHRONIZATION 的部分。

于 2013-08-28T19:50:11.213 回答