如果多个线程并行处理,如何维护数据包的顺序?

时间:2015-06-25 21:02:59

标签: c multithreading sockets pthreads

我正在努力提高用在Linux系统上运行的C编写的网络应用程序的性能。

现在编写的程序从套接字接口读取数据包,对它进行一些处理,然后将其添加到发送队列。

我是多线程编程的新手,但我熟悉基本概念(互斥,条件信号等)。 我正在尝试实现一个解决方案,其中传递一组工作线程从接口读取的内容,然后执行后续工作。

我的问题是如何确保,如果第一个线程读取第一个数据包而第二个线程读取第二个数据包,则数据包添加到发送队列的顺序与读取的顺序相同。

4 个答案:

答案 0 :(得分:0)

只需编码您想要的内容即可。出站数据包可以按顺序插入队列,如果下一个需要发送的数据包不在队列的头部,则发送方可以等待。

答案 1 :(得分:0)

当您说将其添加到发送队列时,您控制的另一个线程是否会将其从此发送队列中删除以便稍后发送,或者这是否在您的控制之外。如果是前者,您可以使用priority queue作为第二个队列而不是传统的先进先出队列。如果优先级队列的密钥是某个全局计数器,则发送方将始终提取最小/下一个值。现在,如果该最小值不是下一个值,则可以从发送方线程中拉出线程等待下一个值。根据优先级队列实现,您还可以查看队列以查看下一个值,然后有条件地等待直到另一个插入队列。

答案 2 :(得分:0)

程序可以为每个线程使用单独的接收和发送队列。接收线程将以循环顺序将数据包排队到处理线程。每个处理线程将数据包从其接收队列中出列,处理数据包并将处理后的数据包排队到其发送队列。发送线程将以循环顺序从已处理的发送队列中取出已处理的数据包。

答案 3 :(得分:0)

有很多方法可以解决这个问题。不同的方式有不同的权衡。需要考虑的是,如果您希望拥有静态数量的工作线程,有多少工作线程,以及您希望解决方案的完美程度。

如果所有工作线程都要通过调用readrecv直接接收数据包,那么:

pthread_mutex_lock(&the_mutex);
do
{
    read_size = read(sock, buf, buf_size);
    if (read_size > 0)
    {
        my_count = ++packet_counter;
        break;
    } else
    {
        // figure out how to handle different failures here
    }
} while (1);
pthread_mutex_unlock(&the_mutex);

results = do_work(buf, read_size);
enqueue_results(my_count, results);

可行,enqueue_results()会将结果放入可以处理密钥环绕的优先级队列中(由于您只是按last_sent_count-this_count排序而不是使用,这并不难做到this_count直接用于队列排序)。 然后另一个线程需要等待下一个回复发送准备好并发送它。

你可以获得更多的发烧友,但你应该尝试一下。