无法让 Unix FIFO 正常工作?

发布于 2024-09-08 19:34:20 字数 620 浏览 3 评论 0原文

我正在尝试在 Linux 中编写一个简单的守护进程,它将创建一个 FIFO,然后收集写入 FIFO 的所有内容,并稍后将该数据写入文件。

我的期望是,一旦我的守护进程创建了 FIFO,我就可以重复执行“echo text > /myfifo”。完成后,我可以执行“echo quit > /myfifo”,我的程序将退出并将所有数据写入磁盘。

我目前正在使用 poll() 来了解 FIFO 上何时有更多数据。在我第一次将数据回显到 FIFO 之前,此功能都可以正常工作。数据回显良好,但此后我的民意调查不断返回 SIGHUP。

在每个进程写入 FIFO 后,我是否需要重置(或关闭并重新打开)FIFO?

我的代码的伪代码如下所示:

ret = fifo(my_fifo, mode);
fd = open(my_fifo, O_RDONLY | O_NONBLOCK);

polling.fd = fd;
polling.events = POLLIN | POLLPRI;

do {
    ret = poll(&polling, 1, -1);
    amt = read(fd, buf, bufsize);
    // do stuff
} while (!done);

I'm trying to write a simple daemon in Linux, which will create a FIFO, then collect anything written to the FIFO and write that data to a file at a later time.

My expectations are that once my daemon has created the FIFO, I can do "echo text > /myfifo" repeatedly. When I'm done, I can do "echo quit > /myfifo" and my program will exit and write all data to disk.

I'm currently using poll() to know when there's more data on the FIFO. This works fine until after the first time I echo data to the FIFO. The data is echoed fine, but my poll continuously returns SIGHUP after that.

Do I need to reset (or close & reopen) the FIFO after each process writes to it?

Pseudo-code of my code looks like this:

ret = fifo(my_fifo, mode);
fd = open(my_fifo, O_RDONLY | O_NONBLOCK);

polling.fd = fd;
polling.events = POLLIN | POLLPRI;

do {
    ret = poll(&polling, 1, -1);
    amt = read(fd, buf, bufsize);
    // do stuff
} while (!done);

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

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

发布评论

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

评论(1

何必那么矫情 2024-09-15 19:34:20

我认为你必须不断重新打开 FIFO。我有一个监视 FIFO 的程序,监视循环是:

/* Implement monitor mode */
void sql_monitor(char *fifo)
{
    if (chk_fifo(fifo) != 0)
        cmd_error(E_NOTFIFO, fifo);

    /* Monitor -- device is assumed to be a FIFO */
    while (1)
    {
        ctxt_newcontext();
        if (ctxt_setinput(fifo) != 0)
            sql_exit(1);
        sql_file();
        ctxt_endcontext();
    }
}

ctxt_newcontext() 函数存储当前 I/O 状态; ctxt_setinput() 函数将输入文件设置为指定文件 - 在本例中为 FIFO。 sql_file() 函数从文件 (FIFO) 中读取数据,直到到达末尾 - 文件被关闭。 ctxt_endcontext() 撤消 ctxt_newcontext() 所做的事情。该过程重复...此代码自大约 1990 年以来一直存在。

因此,,在读取文件末尾后(在每个过程之后,例如 < code>echo 完成写入 FIFO)。

(您还应该注意到,实际上并不需要轮询 FIFO,除非在没有数据时进程需要执行其他操作。read() 调用将等待,直到有数据为止。返回前的数据。)

You have to keep reopening the FIFO, I think. I have a program that monitors a FIFO, and the monitor loop is:

/* Implement monitor mode */
void sql_monitor(char *fifo)
{
    if (chk_fifo(fifo) != 0)
        cmd_error(E_NOTFIFO, fifo);

    /* Monitor -- device is assumed to be a FIFO */
    while (1)
    {
        ctxt_newcontext();
        if (ctxt_setinput(fifo) != 0)
            sql_exit(1);
        sql_file();
        ctxt_endcontext();
    }
}

The ctxt_newcontext() function stashes the current I/O state; the ctxt_setinput() function sets the input file to the named file - a FIFO in this case. The sql_file() function reads from the file (FIFO) until the end is reached - the file is closed. The ctxt_endcontext() undoes what ctxt_newcontext() does. The process repeats... This code has been around since about 1990.

So, YES, you will need to keep closing and reopening the FIFO after reading the end of the file (after each process such as echo finishes writing to the FIFO).

(You should also notice that there really isn't a need to poll the FIFO unless there's something else for the process to be doing when there is no data. The read() call will wait until there is data before returning.)

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