负载测试中__pthread_mutex_cond_lock_full上的断言失败

时间:2016-11-22 10:15:58

标签: c++ linux pthreads debian mutex

我使用以下代码在我在debian 8上运行的c ++应用程序中创建一个计时器对象。

class Timer
{
private:
    std::condition_variable cond_;
    std::mutex mutex_;
    int duration;
    void *params;

public:
    Timer::Timer(void (*func)(void*))
    {
      this->handler = func;
      this->duration = 0;
      this->params = NULL;
    };

    Timer::~Timer(){};

    void Timer::start(int duree, void* handlerParams)
    {
      this->duration = duree;
      this->params   = handlerParams;
      /*
       * Launch the timer thread and wait it
       */
      std::thread([this]{
                std::unique_lock<std::mutex> mlock(mutex_);
                std::cv_status ret = cond_.wait_for(mlock, 
                                     std::chrono::seconds(duration));
                if ( ret ==  std::cv_status::timeout )  
                {
                    handler(params);
                }
              }).detach();

      };

      void Timer::stop()
      {
          cond_.notify_all();
      }
    };

它在gdb和正常条件下正常工作,但在30个或更多请求的负载测试中,它与断言崩溃:

nptl / pthread_mutex_lock.c:350:__ pthread_mutex_cond_lock_full:断言`( - (e))!= 3 || !强大的&#39;失败。

我不明白这个断言的原因。有人可以帮我吗? 谢谢

2 个答案:

答案 0 :(得分:0)

基本上你有一个访问计时器对象的分离线程,所以很可能你破坏了Timer对象,但线程仍在运行并访问它的成员(互斥,条件变量)。 / p>

断言本身从glibc源代码中说,互斥锁的所有者已经死亡。

答案 1 :(得分:0)

非常感谢您的评论!我将尝试更改线程分离,并进行负载测试。 这是我的问题的MVCE,它是巨大应用程序的一部分。

/**
 * \file Timer.hxx
 * \brief Definition of Timer class.
 */
  #include <chrono>
  #include <thread>
  #include <mutex>
  #include <condition_variable>

    class Timer
    {
    private:
    std::condition_variable cond_;
    std::mutex mutex_;
    int duration;
    void *params;

    public:
    Timer(void (*func)(void*));
    ~Timer();

    void (*handler)(void*);
    void start(int duree, void* handlerParams);
    void stop();
    };

 /*
 * Timer.cxx
 */
 #include "Timer.hxx"
 Timer::Timer(void (*func)(void*))
{
//this->set_handler(func, params);
this->handler = func;
this->duration = 0;
this->params = NULL;
}

Timer::~Timer()
{
}

void Timer::start(int duree, void* handlerParams)
{
this->duration = duree;
this->params   = handlerParams;
/*
 * Launch the timer thread and wait it
 */
std::thread([this]{
                std::unique_lock<std::mutex> mlock(mutex_);
                std::cv_status ret = cond_.wait_for(mlock, std::chrono::seconds(duration));
                if ( ret ==  std::cv_status::timeout )  
                {
                    handler(params);
                }
              }).detach();

   }


 void Timer::stop()
 {
  cond_.notify_all();
 }

/*
 * MAIN
 */
#include <stdio.h>
#include <iostream>
#include <unistd.h>
#include "Timer.hxx"

using namespace std;

void timeoutHandler(void* params)
{
char* data= (char*)params;
cout << "Timeout triggered !! Received data is: " ;
if (data!=NULL)
    cout << data << endl;   
}

int main(int argc, char **argv)
{
int delay=5;
char data[20] ="This is a test" ;

Timer *t= new Timer(&timeoutHandler) ;
t->start(delay, data);
cout << "Timer started !! " << endl;    
sleep(1000);
t->stop();
delete t;
cout << "Timer deleted !! " << endl;    

return 0;
}