题
会发生什么,如果我有一个插座, s
, 没有当前可用的数据,这是一个阻止插座,和我通话 recv
关于它从两个线程的一次?将一个线程获得数据?都将得到它?将2号呼叫 recv
带回一个错误?
解决方案
一个线程将得到它,并且没办法告诉其中。
这看起来不像一个合理的设计。是有一个理由为什么你需要两个线呼叫 recv()
在同一座?
其他提示
套接字实现应该是线程安全的,所以只有一个线程应该得到的数据时可用。另一个呼叫应该只是阻塞。
我找不到这样的参考,但这里是我的理解:
的线程安全可能仅仅意味着多个线程可以分别安全地使用他们的自己插座供应商的保证;它并不能保证的原子强>在单个呼叫,而它并不保证在多个线程之间套接字的数据的任何特定配置。
假设线程A调用的recv()这是接收TCP数据以高速率流中的插座上。如果的recv()需要一个原子调用,那么线程A可以阻止所有其他线程执行的,因为它需要连续运行中的所有数据拉(直到缓冲区满,反正)。这将不会是好。因此,我不会假定的recv()是免疫上下文切换。
相反,假设线程A使一个的阻断拨打到的recv()上的TCP套接字,并且该数据被慢慢英寸因此,调用的recv(),并将errno设置为EAGAIN返回。
在这两种情况下,假设线程B调用的recv()在同一插座上,而线程A仍在接收数据。什么时候线程A停止获取交给它,这样线程B可以开始接收数据的数据?我不知道一个Unix的实现,会尽量记得,线程A是在插座上的操作的中间;相反,它是由应用程序(线程A和B)以协商它们的使用。
一般地,这是最好的设计应用程序,以便只有一个线程将在单个插座调用的recv()。
从上的recv href="http://www.mkssoftware.com/docs/man3/recv.3.asp" rel="nofollow noreferrer">人页的
一个的recv()上的插座SOCK_STREAM
返回尽可能多的可用信息
作为缓冲罐供给的大小
持。 让我们假设使用的是TCP,因为它不是在问题指定。因此,假设你有线程A和线程B都阻塞的recv()套接字秒。一旦s已被接收的一些数据会解锁一个线程,可以说A,并返回数据。返回的数据会出现一些随机的大小就我们而言。线程A检查接收到的数据,并决定,如果它有一个完整的“消息”,其中一个消息是应用层次的概念。 主题A决定它不具有一个完整的消息,所以它()再次调用的recv。但在此期间B在已经挡住了同一个插座上,并已收到了用于线程A我使用意松散这里的“消息”的其余部分。 现在既线程A和线程B具有不完整的消息,并且将取决于代码是如何写的,扔离数据为无效,或导致奇怪和细微的错误。 我希望我能说我没有从经验中知道这一点。 所以,当的recv()本身在技术上是线程安全的,这是一个坏主意,有两个线程同时调用它,如果你正在使用它的TCP。 据我所知,这是完全安全的,当你使用UDP。 我希望这有助于。