【发布时间】:2017-03-21 20:41:42
【问题描述】:
我已经编写了一个 C 应用程序来对 DNS 服务器(在 VM 上运行)进行压力测试,我正在尝试获得最大的 DNS 请求率(吞吐量)以查看它的行为。
我的应用程序运行两个线程,发送线程生成 DNS 请求(具有不同的查询名称)并将它们通过套接字发送到服务器,以及接收线程在同一套接字上接收 DNS 响应并计算响应时间。
现在使用并发链表(我已经实现),发送线程为每个发送的请求附加查询名称和发送时间(到列表的末尾)。接收线程每次从一开始就运行,查找具有相关发送时间的查询名称,计算响应时间并从列表中删除对象,它遍历的每个对象都检查发送时间是否在 DNS 超时窗口内设置,如果不是,我将此请求视为未答复并将其从列表中删除。
现在的问题是,每次在包含节点删除的接收线程中遍历整个列表时,我都必须锁定它,它严重影响停止发送的发送线程,等待大量时间锁定附加.
在我的情况下,您会建议以不同的方式实现锁定吗?或者也许我可以改变一些更重要的事情?
PS:我尝试在脚本中使用 unix dig 并在 python scapy 中实现相同但无法达到我在 C 应用程序中达到的速率(不锁定发送已到 10 Mbit),这就是我选择在 C 中实现它的原因。
谢谢!
【问题讨论】:
-
您可以在时间戳上使用哈希,并为每个存储桶使用锁。您也可以尝试一种简单的读取时复制方法,即在读取之前复制列表。
-
如果您使用带有单个事件分派循环的单线程模型,这可能不会更糟。然后可以在多个处理器上运行循环的多个实例(彼此独立)以生成更多请求。每个循环只处理 它 生成的回复,这些回复在它自己的私有链表中。这可能是
fork-ed 到多个子进程。
标签: c multithreading concurrency concurrentmodification locks