C++ 在select()上被阻止时发送到()
当主线程在同一套接字的C++ 在select()上被阻止时发送到(),c++,c,linux,sockets,winsock2,C++,C,Linux,Sockets,Winsock2,当主线程在同一套接字的select()上被阻塞以检查可读性时,我是否可以从套接字上的其他线程调用sendto()?这种行为是在linux或windows等不同系统中定义的吗?或者我必须始终只从同一个线程执行与套接字相关的操作(select()/sendto()/recvfrom())吗?我在应用程序中使用这种体系结构。我已经检查了多个源代码(针对Linux),没有发现任何与之相反的内容 此概念唯一的正式基础是POSIX标准——它表示 sEdtoTo()/以及选择()>代码>是线程安全的函数: P
select()
上被阻塞以检查可读性时,我是否可以从套接字上的其他线程调用sendto()
?这种行为是在linux或windows等不同系统中定义的吗?或者我必须始终只从同一个线程执行与套接字相关的操作(select()
/sendto()
/recvfrom()
)吗?我在应用程序中使用这种体系结构。我已经检查了多个源代码(针对Linux),没有发现任何与之相反的内容
此概念唯一的正式基础是POSIX标准——它表示<代码> sEdtoTo()/<代码>以及<代码>选择()>代码>是线程安全的函数:
POSIX.1-2001和POSIX.1-2008要求标准中规定的所有功能应为线程安全的,以下功能除外 (sendto
和select
未列出)来自
所以,如果函数是线程安全的,那么它的内部结构是安全锁定的,那么混合使用这两个函数也可以。但是,我认为将select()
与recvfrom()混合使用是不正确的。也许它不会损坏程序,但唤醒两个等待的线程将生成竞争条件
关于winsock,文档必须检查它的实现如何遵循POSIX标准。我唯一发现的是,这部分回答了你的问题。在Linux中,您可以检查它的开源代码:
更新:
还有一个有用的链接我在应用程序中使用了这种体系结构。我已经检查了多个源代码(针对Linux),没有发现任何与之相反的内容
此概念唯一的正式基础是POSIX标准——它表示<代码> sEdtoTo()/<代码>以及<代码>选择()>代码>是线程安全的函数:
POSIX.1-2001和POSIX.1-2008要求标准中规定的所有功能应为线程安全的,以下功能除外
(sendto
和select
未列出)来自
所以,如果函数是线程安全的,那么它的内部结构是安全锁定的,那么混合使用这两个函数也可以。但是,我认为将select()
与recvfrom()混合使用是不正确的。也许它不会损坏程序,但唤醒两个等待的线程将生成竞争条件
关于winsock,文档必须检查它的实现如何遵循POSIX标准。我唯一发现的是,这部分回答了你的问题。在Linux中,您可以检查它的开源代码:
更新:
另一个有用的链接在我看来,从另一个线程调用sendto
时应该没有任何问题
“主线程在select()上被阻止”
这只意味着它是一个阻塞调用-它并不意味着它会阻止其他人访问此资源(在本例中为套接字)。从我的角度来看,从另一个线程调用sendto
时不应该有任何问题
“主线程在select()上被阻止”
这只意味着它是一个阻塞调用-这并不意味着它阻止其他人访问此资源(本例中为套接字)。您可以,但它看起来像一个奇怪的设计
你可以
select
和sendto
都作用于套接字,并且套接字可以在线程甚至进程之间共享,只要您同步它们,或者一个用于读取,一个用于写入。如果在两个线程上混合写入或读取,唯一的风险是只获取部分数据(另一个线程获取另一部分),或者由于写入的数据是混合的而产生垃圾。如果一个线程使用选择
进行读取,而另一个线程使用写入
,发送
或发送到
进行写入
,我看不出有任何问题
也许你不应该
Threads和select是实现相同目标的两种方法:在同一进程中处理不同的通信通道。在执行线程时,常用的方法是在每个通道上指定一个线程,并让线程库或操作系统在每个线程有事情要做时为其分配处理器时间,就像所有线程同时执行一样。它导致了一些简单的程序,在这些程序中,您可以一次编写一个任务
创建select
系统调用是为了有一个中心点,该中心点被告知哪些通信通道需要采取行动,然后对其进行明确的处理。这样,您就有了一个单独的等待点,可以触发短期操作。您可以手动决定在什么时候应该做什么,并且可以确保除了在select
调用中,永远不会被阻止。它导致了非常高效的代码(没有上下文更改开销),但代价是编写起来更加复杂,因为您只编写小动作而不是整个任务
通常,如果您使用select
方式,则应仅将线程用于长计算异步任务,而不用于与IO相关的任务。这就是为什么我认为你现在的设计很奇怪的原因
你可以,但它看起来像一个奇怪的设计
你可以
select
和sendto
都作用于套接字,并且套接字可以在线程甚至进程之间共享,只要您同步它们,或者一个用于读取,一个用于写入。如果在两个线程上混合写入或读取,唯一的风险是只获取部分数据(另一个线程获取另一部分),或者由于写入的数据是混合的而产生垃圾。如果一个线程使用选择
进行读取,而另一个线程使用写入
,发送
或发送到
进行写入
,我看不出有任何问题