一个任务如何在多个 vxworks 队列上等待?

发布于 2024-07-06 02:56:26 字数 163 浏览 9 评论 0原文

我们有一个 vxWorks 设计,需要一个任务来处理来自两个消息队列 Q1 和 Q1 的消息。 Q2。

我们希望在两个队列上等待,无论哪个队列收到消息,都处理队列中的消息。

我们希望避免轮询队列或使用可能导致其他队列填满的超时值。

有没有办法做到这一点?

We have a vxWorks design which requires one task to process messages from two message queues, Q1 & Q2.

We would like to wait on both Queues and whichever gets a message, process the message from the queue.

We want to avoid either polling the queues or using a timeout value which could cause the other queue to fill up.

Is there a way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

静若繁花 2024-07-13 02:56:26

如果使用命名管道(pipeDevCreate()、write()、read())而不是消息队列,则可以使用 select() 进行阻塞,直到任一管道中有消息为止。

每当 select() 触发时,您就会处理高优先级管道中的所有消息。 然后处理来自低优先级管道的一条消息。 然后再次调用 select (循环)。

示例代码片段:

 // Initialization: Create high and low priority named pipes
 pipeDrv(); //initialize pipe driver
 int fdHi = pipeDevCreate("/pipe/high",numMsgs,msgSize);
 int fdLo = pipeDevCreate("/pipe/low",numMsgs,msgSize);

 ...

 // Message sending thread: Add messages to pipe
 write(fdHi, buf, sizeof(buf));

 ...

 // Message processing Thread: select loop
 fd_set rdFdSet;

 while(1)
 {
     FD_ZERO(&rdFdSet);
     FD_SET(fdHi, &rdFdSet);
     FD_SET(fdLo, &rdFdSet;

     if (select(FD_SETSIZE, &rdFdSet, NULL, NULL, NULL) != ERROR)
     {
         if (FD_ISSET(fdHi, &rdFdSet))
         {
             // process all high-priority messages
             while(read(fdHi,buf,size) > 0)
             {
                 //process high-priority
             }
         }

         if (FD_ISSET(fdLo, &rdFdSet))
         {
             // process a single low priority message
             if (read(fdLo,buf,size) > 0)
             {
                 // process low priority
             }
         }
     }
 }

If you use named pipes (pipeDevCreate(), write(), read()) instead of message queues, you can use select() to block until there are messages in either pipe.

Whenever select() triggers, you process all messages in the high priority pipe. Then you process a single message from the low priority pipe. Then call select again (loop).

Example Code snippets:

 // Initialization: Create high and low priority named pipes
 pipeDrv(); //initialize pipe driver
 int fdHi = pipeDevCreate("/pipe/high",numMsgs,msgSize);
 int fdLo = pipeDevCreate("/pipe/low",numMsgs,msgSize);

 ...

 // Message sending thread: Add messages to pipe
 write(fdHi, buf, sizeof(buf));

 ...

 // Message processing Thread: select loop
 fd_set rdFdSet;

 while(1)
 {
     FD_ZERO(&rdFdSet);
     FD_SET(fdHi, &rdFdSet);
     FD_SET(fdLo, &rdFdSet;

     if (select(FD_SETSIZE, &rdFdSet, NULL, NULL, NULL) != ERROR)
     {
         if (FD_ISSET(fdHi, &rdFdSet))
         {
             // process all high-priority messages
             while(read(fdHi,buf,size) > 0)
             {
                 //process high-priority
             }
         }

         if (FD_ISSET(fdLo, &rdFdSet))
         {
             // process a single low priority message
             if (read(fdLo,buf,size) > 0)
             {
                 // process low priority
             }
         }
     }
 }
人疚 2024-07-13 02:56:26

在vxWorks中,不能直接在多个队列上等待。 但是,您可以使用操作系统事件(来自 eventLib)来实现此结果。
以下是一个简单的代码片段:


MSG_Q_ID lowQ, hiQ;

void Init() {
// Task Initialization Code.  This should be called from the task that will
// be receiving the messages
...
hiQ = msgQCreate(...);
lowQ = msgQCreate(...);
msgQEvStart(hiQ, VX_EV01);  // Event 1 sent when hiQ receives message
msgQEvStart(loQ, VX_EV02);  // Event 2 sent when loQ receives message
...
}
void RxMessages() {
...
  UINT32 ev;   // Event received

   // Blocks until we receive Event 1 or 2
   eventReceive(VX_EV01 | VX_EV02, EVENT_WAIT_ANY, WAIT_FOREVER, &ev);
   if(ev & VX_EV01) {
      msgQReceive(hiQ, ...);
   }
   if(ev & VX_EV02) {
      msgQReceive(loQ, ...);
   }
}

请注意,您需要修改该代码,以确保在收到多条消息的情况下排空所有队列。

使用 semEvStart() 函数也可以将相同的机制应用于二进制信号量。

In vxWorks, you can't wait directly on multiple queues. You can however use the OS events (from eventLib) to achieve this result.
Here is a simple code snippet:


MSG_Q_ID lowQ, hiQ;

void Init() {
// Task Initialization Code.  This should be called from the task that will
// be receiving the messages
...
hiQ = msgQCreate(...);
lowQ = msgQCreate(...);
msgQEvStart(hiQ, VX_EV01);  // Event 1 sent when hiQ receives message
msgQEvStart(loQ, VX_EV02);  // Event 2 sent when loQ receives message
...
}
void RxMessages() {
...
  UINT32 ev;   // Event received

   // Blocks until we receive Event 1 or 2
   eventReceive(VX_EV01 | VX_EV02, EVENT_WAIT_ANY, WAIT_FOREVER, &ev);
   if(ev & VX_EV01) {
      msgQReceive(hiQ, ...);
   }
   if(ev & VX_EV02) {
      msgQReceive(loQ, ...);
   }
}

Note that you need to modify that code to make sure you drain all your queues in case there is more than one message that was received.

The same mechanism can also be applied to Binary semaphores using the semEvStart() function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文