【问题标题】:Multiple Threads Writing to a Socket多个线程写入一个套接字
【发布时间】:2016-12-28 01:18:27
【问题描述】:

我创建了一个 TCP 客户端应用程序,并决定使用 c 中的 pthread 库通过一个新线程处理传入数据。

但是,我在某处读到,当多个线程尝试写入同一个文件描述符以进行套接字连接时,可能会发生意想不到的事情。

确保这些“意外事件”不会发生的最佳方法是什么。

一开始就需要使用线程吗?

注意:我决定使用线程是为了防止任何阻塞操作。

【问题讨论】:

  • 最好的方法是确保只有一个线程读取/写入套接字。注意:在决定使用线程之前,你需要解释为什么阻塞是不可取的。
  • 投票结束:过于广泛
  • 应用程序是 USSD 应用程序 - 非结构化补充服务数据。它将为多个用户提供服务,有时几乎同时拨打一个短代码。 USSD 网关具有有效的超时,并且要求客户端应用程序在此时间范围内提供响应。当他们不得不等待时,用户体验将受到极大的影响,有时他们的请求可能会超时。
  • @OladipoOlasemo 你知道select()吗?
  • 是的。我读过它。不知道如何在实际代码中实现它。

标签: c++ c sockets


【解决方案1】:

为避免阻塞,您应该研究异步操作。您可以了解您的特定平台如何处理它们,或者使用一个库,例如 ASIO (https://think-async.com/) 来为您处理。

【讨论】:

    【解决方案2】:

    我可以推荐使用 libuv 吗?它高度维护(node.js 的核心)和跨平台。

    另外,你不应该使用select() 那是老派。如果你是自己做的,你应该在 Linux 上使用epoll()。它的扩展性很多更好。

    你应该只有一个作家线程。当套接字不忙时,该线程应该写入。

    Checkout libuv - 它为您处理所有这些混乱,但仍让您靠近金属。 https://nikhilm.github.io/uvbook/networking.html

    我处理此类事情的方法通常是拥有一个写入器线程和一个快速读取器回调,通常只是为传入数据分配内存,然后将其委托给 1 个或多个处理线程。如果你想快速避免memcpy,并分配一个大缓冲区开始。

    【讨论】:

      【解决方案3】:
      • 是的,如果您想在等待传入 TCP 数据时执行其他任何操作,则需要创建线程

      • 是的,您需要注意多线程程序中可能发生的意外情况

      您应该使用互斥锁来防止所谓的意外事件。您用来创建线程的pthread 库也包含同步原语。

      示例程序可能如下所示

      pthread_mutex_t tcp_lock;
      
      void ThreadFunction()
      {
              pthread_mutex_lock(&tcp_lock);
              // Do your stuffs 
              pthread_mutex_unlock(&tcp_lock);
      }
      
      int MainThread()
      {
          pthread_mutex_lock(&tcp_lock);
          // Do your stuffs
          pthread_mutex_unlock(&tcp_lock);
      }
      

      【讨论】:

      • “是的,如果你想在等待传入的 TCP 数据时做其他事情,你需要创建线程”,不。人选,民意调查。它们有很多做服务器的方法,线程就是其中之一。
      • 不,如果你想在等待传入的 TCP 数据时做任何其他事情,你不需要创建线程。您可以使用非阻塞或多路复用或异步 I/O。
      • select、poll、epoll是最好的机制,如果你不想在socket没有数据的时候阻塞你的线程。
      猜你喜欢
      • 1970-01-01
      • 2014-08-01
      • 2012-05-17
      • 2023-03-19
      • 1970-01-01
      • 2013-11-21
      • 1970-01-01
      • 2016-11-08
      • 1970-01-01
      相关资源
      最近更新 更多