2010-06-02 19 views
2

我正在尝试在Linux下编写2个服务器/客户端程序,它们通过命名管道进行通信。问题是,有时当我尝试从服务器写入一个不再存在的管道(客户端已停止)时,出现“资源暂时不可用”错误,并且服务器完全停止。Linux中的“写入”功能的问题

据我所知,这是由于在打开fifo chanel时使用O_NONBLOCK参数引起的,表明程序通常会等待,直到它可以再次写入文件中,但有没有办法阻止这种行为,以及如果发生问题,不要停止整个程序(不应该写命令返回-1广告程序正常继续)?

而另一个奇怪的是,这个错误只发生在ide(日食)之外的程序运行。如果我在eclipse中运行这两个程序,错误时写入函数只返回-1,程序正常继续。

回答

6

如果您希望write()到返回-1错误(并设置errnoEPIPE),而不是停止你的服务器完全地当你的管道写端未连接,您必须忽略信号与signal(SIGPIPE, SIG_IGN)

+0

谢谢......我刚测试过它,它工作。 – 2010-06-02 14:28:39

-2

也许你可以把它包装成一个“try..catch”语句?

+0

尝试过......没有工作 – 2010-06-02 09:49:40

+3

Linux不会抛出C++异常...... – Nikko 2010-06-02 10:00:40

2

这个未定义行为的问题很奇怪,你可能在某处存在内存问题,或者你错过了一个测试。 (或Eclipse的做一些特别的东西来处理信号?)

+0

这个问题肯定与写入功能有关。我在写入调用之前和之后放置了2个“perror”...只有第一个显示,因此程序存在于“写入”函数调用中。我忘了提及,当客户端关闭时,它也会从磁盘上删除文件,所以从服务器剩下的文件描述符指向......什么都不是。 – 2010-06-02 10:21:30

+0

@Dumitru:没有任何代码证明你在说什么,这个答案似乎是最好的选择,特别是考虑到你在问题中描述的所有行为。 – 2010-06-02 10:23:24

+0

你应该用鸭嘴兽解决方案进行测试,但行为很奇怪 – Nikko 2010-06-02 11:59:36

0

引用第2节手册页进行编写: “[errno =] EPIPE尝试写入任何进程未打开以供读取的管道或FIFO,或者只有一端打开(或通过套接字(3SOCKET)创建的文件描述符,使用SOCK_STREAM类型,该类型不再连接到对等端点)SIGPIPE信号也将被发送到线程。进程死亡,除非采取特殊措施来捕获或忽略信号。“”[重点是我的]。

由于Platypus说你需要忽略SIGPIPE信号: signal(SIGPIPE, SIG_IGN)。您也可以捕捉信号并以不同的方式处理服务器中的管道断开。