valgrind在多线程套接字程序中停止

问题描述 投票:5回答:4

我正在用valgrind运行多线程套接字程序。客户端将通过TCP向服务器发送请求,然后忙于等待布尔值。当调用服务器响应服务的回调函数时,将设置布尔值。一旦收到响应(并设置了布尔标志),服务器将再次发出请求,并在循环中重复执行此操作。

我意识到对共享变量的非同步访问(布尔值)会导致线程问题,但我尝试使用pthread互斥,并且程序减慢了大约20%(速度在这里很重要)。我有信心写共享布尔变量很好,因为它可以在一个循环中完成。

该程序在valgrind之外运行良好,但在使用valgrind运行时经常会失速。我让程序一夜之间运行..通常需要几秒钟才能完成,所以我不认为这是一个不等待程序完成的情况。线程由开源引擎框架(快速修复)管理,因此我不认为这是如何创建/管理线程的问题。

有没有人知道valgrind在多线程程序/忙等待循环/套接字通信(或这些的组合)周围的任何问题?

multithreading valgrind
4个回答
8
投票

虽然其他答案侧重于坚持你采用标准同步方法(我完全同意的方式),但我想我应该回答你关于Valgrind的问题。

据我所知,Valgrind在多线程环境中运行没有问题。我相信Valgrind强制应用程序在单个核心上运行,但除此之外它不应该影响你的线程。

Valgrind可能对您的应用程序做了什么改变了线程之间的时间和交互方式,这可能会暴露您在运行独立时通常看不到的代码中的错误和竞争条件。

在我看来,您应用于判断错误不在您正在使用的开源线程框架中的相同逻辑也适用于Valgrind。我建议您将这些挂起视为代码中的错误并对其进行调试,因为这很可能就是它们的原因。

作为旁注,使用互斥锁对于您描述的问题可能有点过分。您应该调查信号量或条件变量。

祝好运。


3
投票

读/写布尔值不是x86上的原子操作。

在这里看到我的问题:Is volatile a proper way to make a single byte atomic in C/C++?


2
投票

即使编写布尔值是一个原子操作,compiler and the CPU are free to re-order the update也可以访问其他内存。忙等待的线程可能会从繁忙的循环中唤醒,并发现共享数据结构尚未实际更新。

我强烈建议您坚持使用可用的线程原语来编写一致的程序,每次都按照您的要求执行。


2
投票

我刚遇到类似的问题。像OP一样,我有一个线程忙着等待。在我的情况下,问题是繁忙的等待几乎占用了所有CPU周期并导致其他线程运行速度慢了数千倍。起初我通过在忙等待循环中放置一个usleep(1)来修复此问题(仅适用于Valgrind构建)。然后我阅读了Valgrind手册并了解了--fair-sched = yes选项,它还解决了问题并允许我删除usleep(1)。

© www.soinside.com 2019 - 2024. All rights reserved.