C ++ Linux命名管道通过O_WRONLY挂在open()上 [英] C++ Linux named pipe hanging on open() with O_WRONLY

查看:317
本文介绍了C ++ Linux命名管道通过O_WRONLY挂在open()上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

This is my simple code that opens a named pipe, writes a string to it, and then closes the pipe. The pipe is created in a another function, as mentioned below.

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)来创建管道

but the call to open() hangs. I've made sure that there is no other process using the fifo "jobqueue" at the time of calling and the file permissions for the queue once it's created are set prwxrwxr-x (I'm just using mkfifo(ipcnm, 0777) to create the pipe.

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

I thought at first that it was a problem the that group o is missing w permissions on this pipe, so i manually changed them with chmod and it still hangs, as "queue opened" never gets printed. Nor does the error message for perror("open");

我想念什么?

推荐答案

打开FIFO进行写入时,写入器将被阻塞,直到有读取器为止.

When you open a FIFO for writing, the writer is blocked until there is a reader.

您可能想念读者.

您无法写入管道,然后将其关闭,然后让阅读器随身携带.这种存储语义是通过使用常规文件来实现的.

You cannot write to a pipe, then close it, and then have the reader come along later. Such storage semantics is accomplished by using a regular file.

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

Pipes are an inter-process communication mechanism; a pipe created by opening a FIFO is similar to the object returned by the pipe POSIX C library function, except that pipe returns an object which is already prepared for I/O, since there are two descriptors: opposite ends open for opposite directions of I/O. Whereas a FIFO's endpoints are separately opened one at a time.

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

The FIFO object in the filesystem is only a contact point which allows multiple processes to attach to the same pipe.

最初,不存在管道对象.当第一个进程在文件系统中的FIFO对象上执行open时,将创建一个管道.来自同一进程或另一个附加到内核中保存的同一管道对象的任何其他open请求.只有在打开管道至少一次以进行读取并至少打开一次以进行写入之前,才能进行I/O操作.实际的管道I/O通过内核.它没有存储在文件系统中.当所有进程关闭管道时,对象就会消失.

Initially, no pipe object exists. When the first process executes an open on the FIFO object in the filesystem, a pipe is created. Any additional open requests from the same process or another attach to the same pipe object held in the kernel. I/O cannot take place until the pipe is opened at least once for reading and at least once for writing. The actual pipe I/O goes through the kernel; it is not stored in the filesystem. When all processes close the pipe, the object goes away.

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

A FIFO could be designed such that I/O can begin before any process has the object open for reading. That is to say, a write request could be allowed to proceed and then block only when the pipe fills up. That design would have issues. For instance, what if the write is small, so that the pipe does not fill up? The writer will write the data and proceed in its execution. If it simply exits before a reader has read the data, the data has disappeared forever! The blocking behavior ensures that a reader is there to catch the data; when the writer is unblocked, it can be sure that a reader has the pipe open, and so it can safely close its end of the pipe without the data being lost. A design which does not block writes even when no reader is available would have to keep the pipe object around inside the kernel even when no process has it open, so that a writer can open a pipe, put data in it, then go away, and later a reader can pick up the data. Or else the design would have to provide, to the writer, a blocking close (similarly to SO_LINGER-arranged behavior on a socket) which waits for previously written data to be removed.

这篇关于C ++ Linux命名管道通过O_WRONLY挂在open()上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆