【问题标题】:C socket API is thread safe? [duplicate]C套接字API是线程安全的吗? [复制]
【发布时间】:2011-01-22 04:52:15
【问题描述】:

我同时使用 Linux 和 Win32 套接字 API。在我的程序中,多个线程共享一个套接字句柄。特别是,多个线程使用共享套接字句柄(即相同的端口)调用send。在这种情况下,我是否必须为线程安全加锁?我无法找到答案。我可能会做一个测试,但想听听你的经验。

编辑:我知道这样通过套接字发送数据根本不是原子操作。当然,我们必须使用互斥锁来保证线程安全。但是,我想知道系统 API 是否可以有自己的内部锁。如果是这样,我们可以省略自己的锁。

这个问题也可能适用于fprintf 函数。我想知道这样的系统 API 会有自己的锁。根据我的经验,从多个线程调用fprintf 并没有杀死我的程序,尽管文件或标准输出存在竞争(即不一致或不可预测的输出,但程序没有崩溃),这意味着fprintf 有一个锁以保护其内部数据结构。

【问题讨论】:

  • 在我看来,多线程读写同一个套接字是一个事实上的设计问题。

标签: c++ c multithreading networking sockets


【解决方案1】:

通过套接字发送数据不是原子事务 - 任何非原子事务都需要锁定/同步。这与平台无关。

【讨论】:

  • 谢谢。是的,我知道这根本不是原子操作。但是,我想知道系统 API 是否可以有自己的内部锁。
  • 但如果他们这样做了,他们就会变成原子的......
【解决方案2】:

套接字不是 C++ 标准的一部分,因此它取决于实现。通常它们不是线程安全的,因为send 不是原子操作。更多信息请查看this discussion

编辑:操作系统可能有或不能有内部锁来保护内部结构。这取决于实施。所以你不应该指望它。

【讨论】:

  • 听起来 POSIX 发送/接收是基于您的链接和此讨论的线程安全的:stackoverflow.com/a/1981439/602245
  • 如果一个线程执行send操作,另一个执行read操作,这两个线程安全吗?
【解决方案3】:

不,使用 accept 创建的变量不需要是互斥体。线程使用的任何数据至少应该是信号量。

sem_t* sem_data;

【讨论】:

    【解决方案4】:

    我发现在并发环境中调用多个套接字 close() 文件描述符非常危险。

    通常会忽略多个调用,但如果其他线程打开另一个文件描述符,它通常会获取先前的文件描述符,然后噩梦开始。

    【讨论】:

      猜你喜欢
      • 2016-02-22
      • 2016-05-16
      • 2011-03-15
      • 2012-11-12
      • 1970-01-01
      • 1970-01-01
      • 2017-06-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多