2012-04-30 138 views
1

有几个套接字问题,并且找不到明确的是或否,所以如果它是转发,请提前道歉:)平台是Linux 2.6.30,C++应用程序。网络还很新,即将加速。套接字问题

  1. 套接字API线程是否安全?例如,如果我在不使用互斥锁的情况下从多个线程发送数据,还是必须使用自己的互斥锁确保这一点?

  2. 轮询/选择以检查我的发送是否会阻止然后发送,而不仅仅是发送并让发送API内部排队处理发送是否更好?如果线程无论如何会阻塞(如果我不使用超时,那是),我真的不明白为什么需要发送后跟一个发送。

  3. 在Linux中,套接字是否默认为零拷贝,或者是否存在涉及的副本?如果存在副本(不是以API的形式,而是以粒度的形式),是否有大小限制?如果答案是内核确实做了副本,是否有零拷贝套接字?

  4. 如果我必须在两台机器之间进行通信,我会假设多个套接字将比单个套接字使用更好的带宽。这是一个正确的假设吗?在两台普通的Linux机器之间使用全部BW的最佳方式是什么?

5.你最喜欢的测量接口上当前带宽使用情况的工具是什么?这可能只是一个偏好,我看着iptraf等,但希望看到别人使用和喜欢的东西。

回答

3
  1. 套接字API肯定是线程安全的在每个插槽的基础...即只要任何给定的插座仅由一个线程访问,其他线程可以在同一时间内访问其它插槽没有任何问题。让多个线程同时访问同一个套接字可能或者可能不是“线程安全的”(对于一些线程安全的定义),但无论如何都不推荐使用,因为最终的行为不容易预测。 (例如两个线程同时在同一个套接字上调用recv(),哪个线程将从传入的TCP流获得哪些字节?上帝只知道)

  2. 如果您使用阻塞I/O,然后检查在调用send()之前使用poll/select()并不是非常有用,因为即使select()指示您在传出缓冲区中有空间,也可能会阻塞send()。 (例如,如果缓冲区中有32个字节的空间,然后尝试发送64个字节,send()将会被阻止)。 select()和poll()与非阻塞I/O结合使用会更有用。

  3. 我不太确定Linux套接字中零拷贝的状态,但Wikipedia article似乎表明Linux只在使用sendfile(),sendfile64()或splice时执行零拷贝()调用。鉴于现代CPU,无论如何,我怀疑这一切都非常重要 - 除了最高性能的程序之外,所有程序都将具有足够的CPU周期来复制网络数据;网络接口本身的速度将成为瓶颈。

  4. 多个套接字不会为您提供比单个套接字更好的带宽利用率;如果您足够快地将数据通过网络连接,单个套接字可轻松饱和网络连接。特别是多个TCP连接通常会带来比单个TCP连接更差的带宽利用率,因为每个TCP连接都会产生自己的传输开销,更糟糕的是,多个TCP连接将争夺带宽,并且在某些时候开始导致对方丢弃数据包,他们会通过降低发送速率来减少拥塞来应对。

  5. 我无法回答这个问题,在MacOS/X活动监视器下将显示网络带宽使用情况。

1

杰里米的第3点有点不准确。随着多个高速网络接口和大量数据移动,零拷贝变得更加重要。花费在内存中复制缓冲区的时间会影响吞吐量和延迟。异步IO和分散/聚集支持对于高速联网系统至关重要。