gpt4 book ai didi

C++ Linux 命名管道卡在 open() 与 O_WRONLY

转载 作者:IT王子 更新时间:2023-10-29 00:47:53 29 4
gpt4 key购买 nike

这是我的简单代码,它打开一个命名管道,向其中写入一个字符串,然后关闭管道。管道是在另一个函数中创建的,如下所述。

char * ipcnm = "./jobqueue";

std::cout << "opening job queue" << std::endl;

//ensure the jobqueue is opened
if ((jobq = open(ipcnm, O_WRONLY)) < 0) {
perror("open");
exit(-1);
}

std::cout << "queue opened" << std::endl;

// record the number of bytes written to the queue
size_t written = write(jobq, ptr, size*nmemb);

// close fifo
if (close(jobq) < 0) {
perror("close");
exit(-1);
}

// need to report to other agents the size of the job that was written
jobSizes.push_back(written);

但是对 open() 的调用挂起。我已经确保在调用时没有其他进程使用 fifo“jobqueue”,并且队列创建后的文件权限设置为 prwxrwxr-x(我只是使用 mkfifo(ipcnm, 0777) 创建管道。

起初我以为是 o 组缺少此管道上的 w 权限的问题,所以我用 chmod 手动更改了它们,但它仍然挂起,因为“队列打开”永远不会被打印出来。 perror("open") 的错误消息也没有;

我错过了什么?

最佳答案

当您打开一个 FIFO 进行写入时,写入者将被阻塞,直到有读取者为止。

您可能缺少阅读器。

您不能写入管道,然后关闭它,然后再让读取器出现。这种存储语义是通过使用常规文件来实现的。

管道是一种进程间通信机制;通过打开 FIFO 创建的管道类似于 pipe POSIX C 库函数返回的对象,除了 pipe 返回一个已经为 I/O 准备好的对象,因为有两个描述符:相反的两端打开 I/O 的相反方向。而 FIFO 的端点一次单独打开一个。

文件系统中的 FIFO 对象只是一个接触点,它允许多个进程附加到同一个管道。

最初,不存在管道对象。当第一个进程对文件系统中的 FIFO 对象执行 open 时,将创建一个管道。来自同一进程或另一进程的任何附加 open 请求都附加到内核中保存的同一管道对象。在管道至少打开一次用于读取和至少一次用于写入之前,I/O 不会发生。实际的管道 I/O 通过内核;它不存储在文件系统中。当所有进程关闭管道时,对象消失。

FIFO 可以设计成 I/O 可以在任何进程打开对象进行读取之前开始。也就是说,可以允许写入请求继续进行,然后仅在管道填满时才阻塞。这样的设计会有问题。例如,如果写入很小,管道不会填满怎么办?编写器将写入数据并继续执行。如果它在读者读取数据之前就退出了,那么数据就永远消失了!阻塞行为确保读者在那里捕获数据;当写入器被解锁时,可以确定读取器打开了管道,因此它可以安全地关闭管道的末端而不会丢失数据。即使没有可用的读取器也不会阻止写入的设计必须将管道对象保留在内核中,即使没有进程打开它,以便写入器可以打开管道,将数据放入其中,然后离开,稍后读者可以获取数据。否则,设计必须向编写者提供阻塞 close(类似于 SO_LINGER - 在套接字上安排的行为),等待先前写入的数据被删除.

关于C++ Linux 命名管道卡在 open() 与 O_WRONLY,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24099693/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com