我有多线程项目,我通过valgrind使用--tool = helgrind运行它,它显示我几个错误。我正在使用互斥量,但我如何在网上找到如何使用它,你能告诉我什么是错的吗?
#include <iostream>
#include <pthread.h>
#define MAX_THREADS 100
#define MAX_SESSIONS 100
static pthread_mutex_t M_CREATE_SESSION_LOCK= PTHREAD_MUTEX_INITIALIZER;
.....
void connection::proccess(threadVarsType &THREAD) {
....
pthread_mutex_lock(&M_CREATE_SESSION_LOCK);
unsigned int ii;
for (ii=0; ii<MAX_SESSIONS; ii++) {
if (SESSION[ii]==NULL) {
break;
}
}
if (ii==MAX_SESSIONS-1) {
....
pthread_mutex_unlock(&M_CREATE_SESSION_LOCK); // unlock session mutex
....
return;
} else {
....
pthread_mutex_unlock(&M_CREATE_SESSION_LOCK); // unlock session mutex
....
}
....
}
和错误消息:
==4985== Thread #1's call to pthread_mutex_lock failed
==4985== with error code 22 (EINVAL: Invalid argument)
....
==4985== Thread #1 unlocked an invalid lock at 0x4E7B40
==4985== at 0x32CD8: pthread_mutex_unlock (hg_intercepts.c:610)
....
==4985== Thread #1's call to pthread_mutex_unlock failed
==4985== with error code 22 (EINVAL: Invalid argument)
....
==4985== Thread #1's call to pthread_mutex_lock failed
==4985== with error code 22 (EINVAL: Invalid argument)
....
==4985== Thread #1 unlocked an invalid lock at 0x4E7B40
==4985== at 0x32CD8: pthread_mutex_unlock (hg_intercepts.c:610)
....
==4985== Thread #1's call to pthread_mutex_unlock failed
==4985== with error code 22 (EINVAL: Invalid argument)
答案 0 :(得分:4)
首先,始终检查函数调用的返回值。如果pthread调用失败,那么只调用abort()
是一个不错的选择,如果启用了核心转储将进行核心转储,或者如果你正在运行调试器,则调用它。
pthread函数调用真的应该永远不会失败,这意味着你的程序严重错误。在C或C ++程序中,通常会导致神秘故障的是内存损坏。在正常模式下使用valgrind来检查它。
可能导致pthread调用失败的另一件事是不使用-pthread
进行编译。如果使用GCC,则应使用gcc编译和链接gcc -pthread
之类的命令。这将链接pthread库,它将设置一些预处理器定义,这些定义可能对系统的头文件很重要。
有些系统会成功编译和链接使用pthread调用的程序,而不会将其链接到pthread库。这样做是为了使程序或库可以成为线程安全的,而无需实际使用线程。除非链接了真正的pthread库,否则线程调用将链接到虚函数。这可能导致某些函数调用失败。
因此,请确保使用正确的编译器选项构建以包含pthread库。
另一个可能的原因是,如果你正在建立一些糟糕的半混合操作系统,它从Linux 2.4开始,并在某个时候升级到Linux 2.6 NPTL(我曾经做过类似的事情)。如果您尝试使用过时的PTHREAD_MUTEX_INITIALIZER
定义或pthread_mutex_t
类型的错误大小来编译旧头文件,那么可能会导致问题。
答案 1 :(得分:2)
该错误表明互斥锁初始化有问题。这很难做到,但要确保你在正确的位置初始化它。
答案 2 :(得分:2)
在Helgrind docs page上,他们提到可能存在被假设被抑制的误报......不知怎的,你可能会碰到那些,因为表面看来你似乎没有使用pthread互斥量不正确。
这是他们写的:
Helgrind的错误检查不起作用 正确地在系统线程内部 库本身(libpthread.so),它 通常会观察到大量的 (错误)那里的错误。 Valgrind的的 抑制系统然后过滤这些 出去,所以你不应该看到它们。
如果您发现任何比赛错误报告 其中libpthread.so或ld.so是 与最里面相关联的对象 堆栈框架,请提交错误报告 在http://www.valgrind.org/。
他们还注意到你应该使用“支持的Linux发行版”...他们没有提到究竟是什么意思,但是如果你使用的是非Linux操作系统,这也可能导致其中一些“误报”。可能值得请求开发团队了解他们对此的看法。
答案 3 :(得分:0)
对EINVAL
的调用中的错误pthread_mutex_lock
表示两件事之一。
The mutex was created with the protocol attribute having the value PTHREAD_PRIO_PROTECT and the calling thread's priority is higher than the mutex's current priority ceiling.
或
The value specified by mutex does not refer to an initialised mutex object.
第二个似乎更有可能。尝试使用main
初始化int error = pthread_mutex_init(&M_CREATE_SESSION_LOCK, NULL);
函数中的互斥锁,并检查是否存在错误,而不是像您当前那样使用宏初始化它。