分类: LINUX
2015-08-12 17:09:07
If O_NONBLOCK is clear:
An open() for reading only will block the calling thread until a thread opens the file for writing. An open() for writing only will block the calling thread until a thread opens the file for reading.
When opening a block special or character special file that supports non-blocking opens:
If O_NONBLOCK is set:
The open() function will return without blocking for the device to be ready or available. Subsequent behaviour of the device is device-specific.
If O_NONBLOCK is clear:
The open() function will block the calling thread until the device is ready or available before returning.
Otherwise, the behaviour of O_NONBLOCK is unspecified.
《read》
When attempting to read from an empty pipe or FIFO:
When attempting to read a file (other than a pipe or FIFO) that supports non-blocking reads and has no data currently available:
现在简要说明一下遇到的问题:
要通过FIFO来进行进程间通信,用阻塞模式打开的话,进程会block在open函数上。估计谁也不希望在一个ipc类的initialize函数里面打开fifo文件时被block住。所以解法就是用非阻塞模式打开(|O_NONBLOCK),打开的问题我们解决了。
但这样我们还是没有办法像操作普通文件一样用阻塞方式读取数据,就算是用fcntl函数clear掉O_NONBLOCK标识也不行,这是因为上面的一段话“If no process has the pipe open for writing, read() will return 0 to indicate end-of-file. ”,也就是说在没有进程用写模式打开fifo文件的时候,去掉不去掉O_NONBLOCK标识read函数都会直接返回。恰巧我是想用echo向fifo中去写数据。echo不是一个常驻进程,所以在echo还没执行或者执行完以后,我们是没有办法去阻塞读fifo的。(一般的解决方法有:1.用循环,这个办法太土,不予讨论。2.还可以用select或者poll去异步监控fd事件,但感觉很不值当,虽然网上都说要用这种方法。3.用O_ASYNC去触发信号的方法没试过,感觉太繁琐。)
山穷水尽啦,疑无路啦,可这句诗还有后半句,叫"柳暗花明又一村"。
那就是在用只读非阻塞方式打开fifo文件的同时,然后再用只写阻塞方式再次打开该fifo文件。
再来看上面绿色的部分:
A process that uses both ends of the connection in order to communicate with itself should be very careful to avoid deadlocks.
既然man里面没说不许同一个进程同时打开fifo的两端,所以我们这么做一般也不会被人鄙视的。这样的具体原因也在上面的第二段绿色文字中:
When attempting to read from an empty pipe or FIFO:
If some process has the pipe open for writing and O_NONBLOCK is clear, read() will block the calling thread until some data is written or the pipe is closed by all processes that had the pipe open for writing.
也就是说我们自己保持一个该fifo文件的只写阻塞fd,我们也不会通过这个只写阻塞fd做任何输入操作,只是为了让那个只读fd能在读取数据时block在read函数中。
同时有下面这句作保障:
It can be opened by multiple processes for reading or writing.
从而保障了我们在用只写阻塞方式多打开了一次该fifo文件后,不会对外部的echo操作有任何影响。
特此感谢对open和read两个函数做了详细说明的OpenGroup !!!