相关疑难解决方法(0)

如何通知select()立即返回?

我有一个工作线程正在侦听TCP套接字以获取传入流量,并缓冲接收到的主线程要访问的数据(让我们称之为套接字A).然而,工作线程也有做一些常规操作(比如,每秒一次),即使没有数据进来,所以我用select()了超时,让我不需要保持轮询.(请注意,调用receive()在非阻塞套接字,然后睡一秒钟也不好:输入数据应该是立即可用于主线程,即使主线程可能并不总是能够处理它的时候了,因此需要缓冲.)

现在,我还需要能够发信号通知工作线程立即做其他事情; 从主线程,我需要立即让工作线程select()返回.现在,我已经解决了这个问题(方法基本上从这里这里采用):

在程序启动时,工作线程用于此目的创建数据报(UDP)类型的附加插座,并将其绑定到一些随机端口(我们称之为插座).同样,主线程创建一个用于发送的数据报套接字.在其号召select(),工作线程,将列出一个fd_set.当主线程需要发信号时,它sendto()是相应端口的几个字节localhost.回到工作线程中,如果B保留在fd_setafter select()返回中,则recvfrom()调用并且接收的字节被简单地忽略.

这似乎工作得很好,但我不能说我喜欢这个解决方案,主要是因为它需要为B绑定一个额外的端口,还因为它添加了几个额外的套接字API调用,这可能会失败我猜 - 我不知道真的想要找出每个案件的适当行动.

我认为理想情况下,我想调用一些以A作为输入的函数,除了立即select()返回之外什么都不做.但是,我不知道这样的功能.(我想我可以举例来说shutdown()套接字,但副作用并不是真的可以接受:)

如果这是不可能的,那么第二个最佳选择是创建一个比真正的UDP套接字更糟糕的B,并且实际上并不需要分配任何有限的资源(超出合理的内存量).我想Unix域套接字就可以做到这一点,但是:解决方案不应该比现在的解决方案少得多,尽管一些适量的#ifdef东西都可以.(我主要针对Windows和Linux - 并且顺便编写C++.)

请不要建议重构以摆脱两个单独的线程.这种设计是必要的,因为主线程可能会被长时间阻塞(例如,做一些密集的计算 - 我无法receive()从最里面的计算循环开始定期调用),同时,有人需要缓冲传入的数据(由于我无法控制的原因,它不能是发件人).

现在我正在写这篇文章,我意识到有人肯定会简单地回复" Boost.Asio ",所以我刚刚看了它......但是找不到明显的解决方案.请注意,我也不能(轻松地)影响套接字A的创建方式,但如果需要,我应该可以让其他对象包装它.

c sockets select multithreading

26
推荐指数
1
解决办法
1万
查看次数

标签 统计

c ×1

multithreading ×1

select ×1

sockets ×1