【问题标题】:How can I cancel a blocked read/recvfrom system call on vxworks or linux如何在 vxworks 或 linux 上取消阻止的 read/recvfrom 系统调用
【发布时间】:2013-07-22 06:51:23
【问题描述】:

在任务 I:

...

while (1)
{
  if (running == false)
  break;
  ret = read(fd, buf, size); /* Or: ret = recvfrom(sock, buf, size, 0, NULL, NULL); */
  ...
 }

在任务二中:

...
running = true;
/* ioctl(fd, FIOCANCEL, 0); */
close(fd);   /* Or: close(sock);*/

任务II应该怎么做才能取消被阻塞的任务I,

在vxworks中,有一个函数ioctl(fd, FIOCANCEL, 0)可以取消被阻塞的读或写,但它不能工作。可能是因为驱动不支持“FIOCANCEL”。

如何在vxworks和linux中编写任务二?或者还有其他方法可以完成我的任务吗?

【问题讨论】:

  • 接收到一个信号会导致读返回-1和errno EINTR
  • 意思是任务I“接收信号”?我阻止的任务?怎么调用接收信号函数?
  • 鉴于您使用 Linux 并且您知道任务 1 的进程 ID,您可以通过在任务 2 中调用 kill(pid, SIGUSR1) 向它发送信号。这将导致读取返回 - 1. Errno 将设置为 EINTR。
  • @ZhangBaolei 你知道如何取消VxWorks上的阻塞读任务吗?我在我的应用程序中遇到了同样的问题。

标签: c linux unix vxworks


【解决方案1】:

在 linux 上不可能取消 read/recvfrom 调用。您不能使用相同的 API 编写这些任务。在 Linux 上,您可以使用 epoll 和 O_NONBLOCK 来创建取消 read/recvfrom 的语义。

不可能为 linux 和 vxworks 使用相同的代码。

【讨论】:

    【解决方案2】:

    不要使用阻塞 IO,这是创建没有(可达)退出条件的线程的经典案例,我认为这是一个错误。运行线程的最简单示例如下:

    volatile bool _threadRunning = true;
    
    void taskI()
    {
        int flags = fcntl(fd, F_GETFL, 0);
        fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    
        while (_threadRunning == true)
        {
            ret = read(fd, buf, size);
            if (ret > 0)
            {
                // process buffer
            }
            else
            {
                // sleep for 1 millisecond or so...
            }
        }
        close(fd);
    }
    
    
    void taskII()
    {
        _threadRunning = false;
        _taskI.join();
    }
    

    【讨论】:

      猜你喜欢
      • 2013-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-11
      • 1970-01-01
      • 1970-01-01
      • 2012-04-17
      相关资源
      最近更新 更多