我可以反复切换阻塞和非阻塞行为吗?

时间:2018-05-29 02:24:47

标签: c linux sockets blocking nonblocking

我有两个进程通过主/副本设置中的Unix域套接字进行通信。副本需要定期向主要人员询问指导,但只有在主要表明准备好提供指导时才应该这样做。如果主服务器已就绪,则副本服务器应查询主服务器并等待响应;否则,它应该继续当前的任务。

通常情况下,我会使用POSIX信号量与副本进行通信,无论主服务器是否准备就绪 - 它快速轻便。不幸的是,我碰巧正在研究一种不支持POSIX共享内存的研究系统。因此,Unix套接字就是我所拥有的。

我知道非阻塞读取非常快,所以我想知道我是否可以这样做:

  • 打开副本与主副本之间的连接。
  • 将副本的结尾设置为非阻止。
  • 定期检查副本是否可以从主数据库中读取。
  • 如果读取成功,将套接字切换为阻止并查询主要。查询完成后,将套接字恢复为非阻止
  • 如果读取失败,请继续直到下一次检查。

我可以在阻塞和非阻塞行为之间反复切换套接字吗?

2 个答案:

答案 0 :(得分:2)

You can使用fcntl:

int file_descriptor;
int flags;

// open file_descriptor

flags = fcntl(file_descriptor, F_GETFL, 0);
flags &= ~O_NONBLOCK;           // set blocking
flags |= O_NONBLOCK;            // set non-blocking
fcntl(file_descriptor, F_SETFL, flags);

但是如果你只使用两个插座,我认为你的程序会更简单。使用一个用于控制(非阻塞),一个用于数据(阻塞)。使用控制插座传递"准备好" /"未准备好"消息,以及您的"指南"。

的数据套接字

这消除了重复打开/关闭套接字或修改其配置的需要,并且应该简化程序中的控制流程。它还会分离程序中的数据和控制流,这通常是一种很好的做法。

答案 1 :(得分:2)

我只使用一个带永久阻塞套接字的单独线程。当主要人员准备好被查询时,让他们发送一些东西。尝试接收的线程块:当它发生时,它发出查询等,然后返回初始接收。

编辑将基本无阻塞的系统切换到阻止模式,即使是暂时的,甚至是读取超时也不是一个好主意,因为系统肯定会停止至少超时时间一段时间,具体取决于对等体和中间网络的行为。将这种依赖关系隔离到一个单独的线程,你会好得多。