套接字问题



有几个套接字问题,找不到明确的是或否,所以如果是转发,请提前道歉:(平台是Linux 2.6.30,C++应用程序。对网络仍然很陌生,即将上手。

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

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

  3. 在 Linux 中,套接字是默认为零拷贝,还是涉及拷贝?如果有副本(不是在 API 方面,而是在粒度方面(是否有大小限制?如果答案是内核确实执行复制,是否有零复制套接字?

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

5.您最喜欢测量接口当前带宽使用情况的工具是什么?这可能只是一种偏好,我看了iptraf等,但想看看其他人使用什么和最喜欢的。

  1. 套接字 API 在每个套接字的基础上绝对是线程安全的......即,只要任何给定的套接字仅由一个线程访问,其他线程就可以同时访问其他套接字而不会出现任何问题。 让多个线程同时访问同一个套接字可能是也可能不是"线程安全"(对于线程安全的某些定义(,但无论如何都不建议这样做,因为由此产生的行为不容易预测。 (例如,两个线程几乎同时在同一套接字上调用 recv((,哪个线程将从传入的 TCP 流中获取哪些字节? 只有上帝知道(

  2. 如果你使用的是阻塞 I/O,那么在调用 send(( 之前使用 poll/select(( 进行检查并不是很有用,因为即使 select(( 表明你在传出缓冲区中有空间,你也可能在 send(( 内部阻塞。 (例如,如果缓冲区中有 32 字节的空间,然后您尝试发送 64 字节,send(( 将阻塞(。 select(( 和 poll(( 与非阻塞 I/O 结合使用更有用。

  3. 我不太确定 Linux 套接字中的零拷贝状态,但维基百科的文章似乎表明,Linux 只有在使用 sendfile((、sendfile64(( 或 splice(( 调用时才执行零拷贝。 考虑到现代CPU,我怀疑它无论如何都那么重要 - 除了最高性能的程序之外,所有程序都将有足够的CPU周期可用于复制网络数据;网络接口本身的速度将成为瓶颈。

  4. 多套接字
  5. 不会比单个套接字提供更好的带宽利用率;如果足够快地将数据泵送到网络连接中,单个套接字很容易使网络连接饱和。 特别是多个TCP连接通常会比单个TCP连接提供更差的带宽利用率,因为每个TCP连接都会产生自己的传输开销,更糟糕的是,多个TCP连接将竞争带宽,并在某个时候开始导致彼此丢弃数据包,它们将通过降低发送速率来响应数据包以减少拥塞。

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

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

最新更新