如何等待 n 秒以打开命名管道?

Posted

技术标签:

【中文标题】如何等待 n 秒以打开命名管道?【英文标题】:How can I wait for n seconds for a named pipe to open? 【发布时间】:2019-04-12 18:16:10 【问题描述】:

我有一个程序,当我无法打开管道进行读取时,我想退出 N(比如说 30)秒。

我的代码适用于阻塞名称管道,我无法更改这一点。

我知道 select() 和 poll(),但如果不将管道变为非阻塞状态,我无法让它们工作。

这是我目前的代码:

struct pollfd fds[1];
int pol_ret;

fds[0].fd = open(pipe_name, O_RDONLY /* | O_NONBLOCK */);

if (fds[0].fd < 0)

    // send_signal_to_parent();
    std::cout << "error while opening the pipe for read, exiting!" << '\n';
    return -1;


fds[0].events = POLLIN;

int timeout_msecs = 30000;    //  (30 seconds)
pol_ret = poll(fds, 1, timeout_msecs);

std::cout << "poll returned: "<< pol_ret << '\n';
 if (pol_ret == 0)
 
     std::cout << "im leaving" << '\n';
     return -1;    
 

我怎样才能只等待 30 秒才能打开管道以供读取?

我正在运行 Linux,尤其是 debian。

【问题讨论】:

Linux,尤其是 debian。 对于 select()poll() 都有变体等待您指定的特定超时。另见1, 请至少提供一些代码示例,并解释究竟是什么不工作。 @πάνταῥεῖ 我知道,但我不知道该怎么做。你能举个例子吗? 向我们展示不适合您的代码,并解释您不喜欢的代码。 【参考方案1】:

设置一个带有信号处理程序的计时器并等待在 fifo 上打开调用。 如果打开失败并显示 errno=EINTR 并且您的处理程序运行,则 open 调用被您的计时器中断,即超时。

示例代码:

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>

volatile sig_atomic_t abort_eh;
void handler(int Sig)

    abort_eh = 1;


int main()

    struct sigaction sa;
    sa.sa_flags = 0;
    sa.sa_handler = handler;
    sigemptyset(&sa.sa_mask);
    sigaction(SIGALRM,&sa,0);

    //try to ensure the fifo exists
    (void)mkfifo("fifo",0600);

    //open with a timeout of 1s
    alarm(1);

    int fd;
    do
        if (0>(fd=open("fifo",O_RDONLY)))
            if(errno==EINTR)
                if(abort_eh) return puts("timed out"),1;
                else continue; //another signal interrupted it, so retry
            else return perror("open"),1;
    while(0);

    alarm(0); //cancel timer
    printf("sucessfully opened at fd=%d\n", fd);


setitimertimer_create/timer_settime 提供比alarm 更细粒度的计时器。他们还可以将计时器设置为重复,这允许您在第一个信号“丢失”的情况下重新发出信号(即,在输入 open 调用之前运行,因此未能打破可能无限期阻塞的系统调用)。

【讨论】:

以上是关于如何等待 n 秒以打开命名管道?的主要内容,如果未能解决你的问题,请参考以下文章

在断开连接之前等待读取命名管道

如何写入命名管道而不等待读取管道

命名管道在后台等待客户端,直到客户端连接

命名管道服务器,如何中断或超时等待客户端连接和传入数据

C++ 使用命名管道

命名管道 - 异步窥视