繁体   English   中英

在C中同时修改链表

[英]Concurrent modification of linked list in C

我已经编写了一个C应用程序来对DNS服务器(在VM上运行)进行压力测试,我试图获得最大的DNS请求速率(吞吐量)以查看其行为。
我的应用程序运行两个线程,一个发送线程生成DNS请求(具有不同的查询名称),然后将它们通过套接字发送到服务器;另一个接收线程,它在同一套接字上接收DNS响应并计算响应时间。

现在,这里使用并发链接列表(我已经实现),发送线程为每个发送的请求附加查询名称和发送时间(到列表末尾)。 接收线程每次都从头开始运行,查找具有相关发送时间的查询名称,计算响应时间并从列表中删除对象,它遍历的每个对象还会检查发送时间是否在DNS超时窗口内设置,如果不是,则将该请求视为未答复,然后将其从列表中删除。

现在的问题是,每次在接收线程中也要删除节点时,列表的整个遍历都必须锁定,这严重影响了发送线程,该线程停止发送,在锁上等待了很多时间才能追加。

您是否建议以其他方式实施锁定? 也许还有其他我可以改变的重大事情?

PS:我试图在脚本中使用unix dig并在python scapy中实现相同的功能,但无法达到我在C应用程序中达到的速率(不锁定发送最高可达10 Mbit),这就是为什么我选择了用C实现

谢谢!

你也许并不需要,而接收线程扫描它来锁定整个列表。 发送线程只会修改当前的最后一个节点(以追加一个新节点),并且只要保持指向当前尾部的指针,就不需要检查任何其他节点。 就其本身而言,接收线程然后可以删除除当前尾部以外的任何节点,而不会对发送线程造成任何影响。 因此,仅尾节点需要被锁定。

在当前尾巴上保持移动锁定可能有点棘手,因为您需要知道是哪个节点,但是我认为这不会太难。 例如,您可以提供一个指向尾部的共享原子指针,发送方在发送每个请求之前都会更新尾部,接收方在收到响应后会进行读取。 接收者不需要考虑任何后续请求(因为在收到当前响应时尚未发送这些请求)。

接收者有时可能需要等待发送者追加至少一个请求,以便可以删除以前的尾巴,但是我希望这种情况很少见。 否则,我看不到您的列表现在怎么会这么长,以至于在扫描过程中将整个过程锁定都太耗时。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM