【问题标题】:Send Recv on a socket from Multiple threads从多个线程在套接字上发送 Recv
【发布时间】:2016-09-29 13:20:04
【问题描述】:

我有一个进程 ProcessA 启动 2 个线程 ThreadA 和 ThreadB。两个线程都使用相同的套接字描述符从 ProcessB 发送和接收数据。

所以本质上:

int s;

void thread_fnA(void*)
{
    while(1) {
        sendto(s);
        recvfrom(s);
    }
}

void thread_fnB(void*)
{
    while(1) {
        sendto(s);
        recvfrom(s);
    }
}

int main()
{
      s = socket(AF_UNIX, SOCK_DGRAM, 0);
      bind(s);
      dispatch_thread(A);
      dispatch_thread(B);

}

线程B要接收的消息是否有可能在线程A中接收到。

所以事件顺序:

线程 A 准备消息并调用 sendto();

线程 B 开始执行并准备消息并调用 sendto();

线程 B 与线程 A 同时调用 recvfrom()。

但是两个线程期望的消息内容是不同的。 可以交换消息吗,ThreadB 指定的消息被 ThreadA 接收。

发送和接收是否应该涉及某些锁。 (互斥体)

【问题讨论】:

    标签: linux multithreading sockets network-programming pthreads


    【解决方案1】:

    我会建议另一种设计,您有一个单个线程进行发送和接收,以及其他线程的消息队列。

    当发送/接收线程接收到消息时,它会检查消息的类型,并将其添加到正确处理线程的(受保护的)队列中。处理线程(您当前的线程 A 和 B)从其各自的消息队列中获取消息,并以它喜欢的任何方式处理消息。然后,如果线程 A 或 B 想要发送消息,它会使用另一个队列将消息传递给发送/接收线程,发送/接收线程会轮询该队列。

    或者,处理线程(在您的示例中为 A 和 B)可以直接通过套接字发送。或者每个都有不同的套接字,仅用于发送。

    【讨论】:

    • 所以你的意思是邮件可能放错了。
    • @Haswell 是的,它有可能会发生。
    【解决方案2】:

    由于您在两个线程中使用相同的套接字,因此一个线程可能会读取发往另一个线程的消息。即使你使用互斥体,设计也会非常困难。您可以打开两个套接字(甚至是管道):

    • 一个socket用于A->B方向的通信
    • B->A 方向的第二个插座

    第二种可能性是有一个套接字,一个写入器(线程 A)和一个读取器(线程 B)。阅读器,当它接收到一个数据报时,它可能会根据数据报的有效负载来决定要执行什么任务。或者它也可以将任务发送给其他将处理数据报的工作人员。

    【讨论】:

      猜你喜欢
      • 2023-03-03
      • 1970-01-01
      • 2010-10-14
      • 2013-07-13
      • 2014-11-20
      • 1970-01-01
      • 1970-01-01
      • 2014-11-19
      • 1970-01-01
      相关资源
      最近更新 更多