sendto() 在 select() 上被阻塞
sendto() while blocked on select()
当主线程在 select()
上阻塞时,我可以从套接字上的其他线程调用 sendto()
以检查可读性吗?这种行为是否在 linux 或 windows 等不同系统中定义?或者我是否必须始终只从单个相同的线程做套接字相关的东西(select()
/sendto()
/recvfrom()
)?
我在我的应用程序中使用了这样的架构。我已经检查了多个来源(Linux)并且没有发现任何反对它的东西。
证明此概念的唯一正式基础是 POSIX 标准 - 它说 sendto()
以及 select()
是线程安全函数:
POSIX.1-2001 and POSIX.1-2008 require that all functions specified in the standard shall be thread-safe, except for the following functions
(sendto
和 select
未列出)来自 https://linux.die.net/man/7/pthreads.
所以如果函数是线程安全的,它的内部结构是安全锁定的,那么混合这两个函数应该也可以。但是我认为将 select()
与 recvfrom()
混合使用是不正确的。也许它不会破坏程序,但唤醒两个等待线程会产生竞争条件。
关于 winsock,必须检查文档,它的实现如何遵循 POSIX 标准。我唯一发现的是 is winsock2 thread safe? , which partially anserwrs your question. In Linux you can examine it's opensource code: https://github.com/torvalds/linux/blob/master/net/socket.c https://github.com/torvalds/linux/blob/master/fs/select.c.
更新:
更有帮助 link https://groups.google.com/forum/#!topic/comp.os.linux.networking/cLbMGRNw8EA
从我的角度来看,从另一个线程调用 sendto
应该不会有任何问题。
"main thread is blocked on select()"
这仅意味着它是一个阻塞调用 - 它并不意味着它阻止其他人访问此资源(在本例中为套接字)。
可以,但它的设计看起来很奇怪。
可以。
select
和sendto
都作用于套接字,套接字可以在线程甚至进程之间共享,前提是你同步它们,或者一个读一个写。如果您在 2 个线程上混合写入或读取,唯一的风险是仅获取部分数据(另一个线程获取另一部分)或产生垃圾,因为写入数据是混合的。如果一个线程使用 select
读取而另一个线程使用 write
、send
或 sendto
读取 writing
我看不出有任何问题
也许你不应该。
线程和select是实现同一目标的两种方式:在同一进程中处理不同的通信通道。线程化时,通常的方法是在每个通道上分配一个线程,并让线程库或 OS 在每个线程有事要做时为每个线程分配处理器时间,就好像 所有线程同时执行。它会导致您一次编写一个任务的简单程序。
select
系统调用被创建为具有一个中心点,该中心点被告知什么通信通道需要采取行动,然后明确地处理它。这样一来,您就有一个 waiting 点,预计会触发空头操作。您手动决定在什么时候应该做什么,并且可以确保除了 select
调用外永远不会被阻止。它导致非常高效的代码(无上下文更改开销),但代价是编写起来更复杂,因为您只编写小动作而不是整个任务。
通常情况下,如果你继续select
方式,你应该只使用线程进行长时间计算异步任务,而不是用于IO相关的任务。这就是为什么我认为你现在的设计很奇怪的原因。
当主线程在 select()
上阻塞时,我可以从套接字上的其他线程调用 sendto()
以检查可读性吗?这种行为是否在 linux 或 windows 等不同系统中定义?或者我是否必须始终只从单个相同的线程做套接字相关的东西(select()
/sendto()
/recvfrom()
)?
我在我的应用程序中使用了这样的架构。我已经检查了多个来源(Linux)并且没有发现任何反对它的东西。
证明此概念的唯一正式基础是 POSIX 标准 - 它说 sendto()
以及 select()
是线程安全函数:
POSIX.1-2001 and POSIX.1-2008 require that all functions specified in the standard shall be thread-safe, except for the following functions
(sendto
和 select
未列出)来自 https://linux.die.net/man/7/pthreads.
所以如果函数是线程安全的,它的内部结构是安全锁定的,那么混合这两个函数应该也可以。但是我认为将 select()
与 recvfrom()
混合使用是不正确的。也许它不会破坏程序,但唤醒两个等待线程会产生竞争条件。
关于 winsock,必须检查文档,它的实现如何遵循 POSIX 标准。我唯一发现的是 is winsock2 thread safe? , which partially anserwrs your question. In Linux you can examine it's opensource code: https://github.com/torvalds/linux/blob/master/net/socket.c https://github.com/torvalds/linux/blob/master/fs/select.c.
更新: 更有帮助 link https://groups.google.com/forum/#!topic/comp.os.linux.networking/cLbMGRNw8EA
从我的角度来看,从另一个线程调用 sendto
应该不会有任何问题。
"main thread is blocked on select()"
这仅意味着它是一个阻塞调用 - 它并不意味着它阻止其他人访问此资源(在本例中为套接字)。
可以,但它的设计看起来很奇怪。
可以。
select
和sendto
都作用于套接字,套接字可以在线程甚至进程之间共享,前提是你同步它们,或者一个读一个写。如果您在 2 个线程上混合写入或读取,唯一的风险是仅获取部分数据(另一个线程获取另一部分)或产生垃圾,因为写入数据是混合的。如果一个线程使用select
读取而另一个线程使用write
、send
或sendto
读取writing
我看不出有任何问题也许你不应该。
线程和select是实现同一目标的两种方式:在同一进程中处理不同的通信通道。线程化时,通常的方法是在每个通道上分配一个线程,并让线程库或 OS 在每个线程有事要做时为每个线程分配处理器时间,就好像 所有线程同时执行。它会导致您一次编写一个任务的简单程序。
select
系统调用被创建为具有一个中心点,该中心点被告知什么通信通道需要采取行动,然后明确地处理它。这样一来,您就有一个 waiting 点,预计会触发空头操作。您手动决定在什么时候应该做什么,并且可以确保除了select
调用外永远不会被阻止。它导致非常高效的代码(无上下文更改开销),但代价是编写起来更复杂,因为您只编写小动作而不是整个任务。通常情况下,如果你继续
select
方式,你应该只使用线程进行长时间计算异步任务,而不是用于IO相关的任务。这就是为什么我认为你现在的设计很奇怪的原因。