【问题标题】:Multithreaded sender多线程发送者
【发布时间】:2018-07-17 03:50:52
【问题描述】:

我正在将流量(例如 UDP/TCP 数据包)从一台机器发送到另一台机器。我正在编写一个 C 应用程序,每个流量类型都有 1 个线程。我希望这两个线程同时发送数据包。

我是否需要在 sendMsg 函数中使用任何同步原语,例如互斥锁,因为它是从每个线程调用的?

sockaddr_in dest;

 void * udp(void * arg){
     struct * info = arg;
     int fd = socket(AF_INET, SOCK_DGRAM, 0);
     //set up socket info
     while(1){
         sendMsg(udpInfo, fd);
     }
  }

 void * tcp(void * arg){
     struct * info = arg;
     int fd = socket(AF_INET, SOCK_STREAM, 0);
     // set up socket info
     while(1){
         sendMsg(tcpInfo, fd);
     }
}

     void sendMsg(struct * info, int fd){
         sendTo(fd, "hello", strlen("hello") + 1, 0, (struct sockaddr*)&dest, sizeof(dest));

     }

【问题讨论】:

  • 它不依赖任何共享的数据(假设 dest 不会改变)并且不修改任何数据,因此它不需要任何同步。
  • 不适用于 UDP,但如果您不按顺序排列您的 TCP 发送,您可能会在另一端收到混合数据。 NB sendto() 使用 TCP 会忽略目标参数,并可能导致 EISCONN,除非它们为 NULL 和零。

标签: c multithreading sockets


【解决方案1】:

您似乎对互斥锁的工作原理有点不清楚。互斥锁不是应用于一段代码,而是应用于代码中的一段数据。这里的函数被两个线程调用,但是线程之间没有共享数据。所以正如@Sami Kuhmonen 在上面的评论中所说,你不需要在这里使用互斥锁。

如果有第三个线程将数据推送到(比如说)队列中,那么您将来可能需要一个互斥锁,然后您的线程将从队列中访问该队列并将其发送到连接的计算机。然后,您需要同步这些线程将数据推入和弹出队列的方式。

【讨论】:

  • 那么,两个线程将能够同时在各自的套接字上发送数据包而不会出现任何问题,对吗?如果一个线程进入 sendMsg 并且 send() 调用需要一段时间会发生什么?在第一个线程退出之前,另一个线程会被阻塞吗?
【解决方案2】:

如果您阅读 sendmsg 的手册页,您可能会看到以下句子:

如果消息太长,无法通过底层协议原子传递,则返回错误EMSGSIZE,消息不传输。

Atomically 意味着包总是以一个 blob 的形式发送,没有其他数据能够将自身插入中间。所以不管有多少线程使用 sendmsg,内核都会混合数据包。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-28
    • 2015-06-02
    • 1970-01-01
    • 1970-01-01
    • 2014-10-13
    相关资源
    最近更新 更多