c ++正确使用互斥锁

时间:2011-04-29 19:30:22

标签: c++ pthreads mutex

我有多线程项目,我通过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)

4 个答案:

答案 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);函数中的互斥锁,并检查是否存在错误,而不是像您当前那样使用宏初始化它。