更改互斥锁的优先级

时间:2013-08-26 09:12:48

标签: c mutex vxworks rtos

我是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。

谢谢。

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分: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的部分。