[英]open syscall on fifo not blocking?
我正在创建一个相当大的项目,作为一项家庭作业,在这里我需要创建一个服务器程序,该程序可以监听2个fifo,客户端将在其中编写程序。
一切正常,但是有一些让我生气的事情:每当我执行由客户端和服务器之间的一些读/写操作组成的操作时,当我关闭客户端上的fifos时,看起来服务器“认为”仍然存在有人打开那些fifo。
因此,服务器在每次操作后尝试读取64字节,这很明显失败(读取0字节)。 每次操作仅发生一次,这种情况不会继续尝试读取64字节
它不会给客户带来任何问题,但确实很奇怪,我讨厌那些类型的错误
我认为这与打开/关闭以及客户端使用锁有关。
注意,在此伪代码文本中指定了用于打开操作的标志
服务器行为:
Open Fifo(1) for READING (O_RDONLY)
Open Fifo(2) for WRITING (O_WRONLY)
Do some operations
Close Fifo(1)
Close Fifo(2)
客户行为:
Set a lock on Fifo(1) (waiting if there is already one)
Set a lock on Fifo(2) (same as before)
Open Fifo(1) for WRITING (O_WRONLY)
Open Fifo(2) for READING (O_RDONLY)
Do some operations
Close Fifo(1)
Close Fifo(2)
Get lock from Fifo(1)
Get lock from Fifo(2)
除了用于网络的功能之外,我无法直接发布代码,因为该项目很大,并且我不直接使用syscalls。 这个给你:
int Network_Open(const char* path,int oflag)
{
return open(path,oflag);
}
ssize_t Network_IO(int fifo,NetworkOpCodes opcode,void* data,size_t dataSize)
{
ssize_t retsize = 0;
errno = 0;
if (dataSize == 0) return 0;
while ((retsize = (opcode == NetworkOpCode_Write? write(fifo,data,dataSize) : read(fifo,data,dataSize))) < 0)
{
if (errno != EINTR) break;
}
return retsize;
}
Boolean Network_Send(int fifo,const void* data,size_t dataSize)
{
return ((ssize_t)dataSize) == Network_IO(fifo,NetworkOpCode_Write,(void*)data,dataSize);
}
Boolean Network_Receive(int fifo,void* data,size_t dataSize)
{
return ((ssize_t)dataSize) == Network_IO(fifo,NetworkOpCode_Read,data,dataSize);
}
Boolean Network_Close(int fifo)
{
if (fifo >= 0)
return close(fifo) == 0;
}
任何帮助将不胜感激,谢谢。
编辑1:
客户端输出: http : //pastie.org/2523854 服务器输出(跟踪): http : //pastie.org/2523858
从(阻塞)read()返回的零字节表示文件的一端,即,另一端已关闭FIFO。 阅读手册页以进行阅读。
read()
得出的零字节意味着另一个进程已经完成。 现在,您的服务器必须关闭原始文件描述符,然后重新打开FIFO以服务下一个客户端。 一旦开始使用新文件描述符,阻塞操作将恢复。
这就是它应该起作用的方式。
AFAIK,在您获得零字节之后,进一步尝试读取文件描述符也将永久返回0字节(或直到您关闭文件描述符)。 即使另一个进程打开了FIFO,原始文件描述符也将继续指示EOF(另一个客户端进程将被挂起,等待服务器进程打开FIFO进行读取)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.