8

我正在玩一些套接字、线程和互斥锁。我的问题涉及线程和互斥锁:

int ConnectionHandler::addNewSocket(){

    this->connectionList_mutex.lock();
    std::cout << "test1" << std::endl;
    this->connectionList_mutex.unlock();

    return 0;
}

int ConnectionHandler::main(){
    while(true){
        this->connectionList_mutex.lock();
        std::cout << "test2" << std::endl;
        this->connectionList_mutex.unlock();
    }

}`

main 函数在一个线程中运行,而 addNewSocket 由另一个线程调用。问题是,当 addNewSocket 被调用一次(由第二个线程)时,线程 1(主)的下一次解锁将失败并出现一个奇怪的“信号 SIGABRT”。我现在已经为此工作了两天,但遗憾的是我没有设法解决它。我希望你能帮助我。

编辑: ConnectionHandler 是一个类,它有 connectionList_mutex 作为成员。

编辑:有时我也会收到此错误:“断言失败:(ec == 0),函数解锁,文件 /SourceCache/libcxx/libcxx-65.1/src/mutex.cpp,第 44 行。” 但它是随机发生的。

编辑:这是整个课程(减少到最低限度,应该在一定程度上与上下文无关,但是当我在客户端连接后立即将其放入时崩溃,并且如果我在开始后立即放入它则可以工作:

class ConnectionHandler{
public:
    ConnectionHandler();
    int addNewSocket();
private:
    int main();
    static void start(void * pThis);

    std::mutex connectionList_mutex;
};

ConnectionHandler::ConnectionHandler(){
    std::thread t(&this->start, this);
    t.detach();
}
void ConnectionHandler::start(void * pThis){
    ConnectionHandler *handlerThis;
    handlerThis = (ConnectionHandler *)pThis;
    handlerThis->main();
}


int ConnectionHandler::addNewSocket(){

    this->connectionList_mutex.lock();
    std::cout << "test1" << std::endl;
    this->connectionList_mutex.unlock();

    return 0;
}

int ConnectionHandler::main(){
    while(true){
        this->connectionList_mutex.lock();
        std::cout << "test2" << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        this->connectionList_mutex.unlock();

    }

}
4

1 回答 1

6

我的猜测是您的ConnectionHandler对象正在某处被破坏。另外,您ConnectionHandler::start以愚蠢的方式定义了。

首先,ConnectionHandler::start应该这样定义:

void ConnectionHandler::start(ConnectionHandler * pThis){
    pThis->main();
}

C++11::std::thread类完全能够保留函数参数的类型,因此无需求助于void *.

其次,添加以下代码:

void ConnectionHandler::~ConnectionHandler(){
    const void * const meptr = this;
    this->connectionList_mutex.lock();
    ::std::cout << "ConnectionHandler being destroyed at " << meptr << ::std::endl;
    this->connectionList_mutex.unlock();
}

并将构造函数更改为:

ConnectionHandler::ConnectionHandler(){
    const void * const meptr = this;
    ::std::cout << "ConnectionHandler being created at " << meptr << ::std::endl;
    std::thread t(&this->start, this);
    t.detach();
}

这将显示ConnectionHandler对象何时被销毁。我的猜测是,当您的分离线程仍在运行时,您的代码正在破坏它。

meptr事情是因为有operator <<一个重载void *打印出指针值。this如果要创建多个ConnectionHandler对象,打印出指针值将允许您匹配对构造函数和析构函数的调用。

编辑:因为事实证明我是正确的,所以我建议你编写 play ConnectionHandler 类:

#include <iostream>
#include <atomic>
#include <thread>
#include <chrono>
#include <mutex>

class ConnectionHandler {
 public:
   ConnectionHandler();
   ~ConnectionHandler();
   ConnectionHandler(const ConnectionHandler &) = delete;
   const ConnectionHandler &operator =(const ConnectionHandler &) = delete;

   int addNewSocket();

 private:
   int main();
   static void start(ConnectionHandler * pThis);

   ::std::mutex connectionList_mutex;
   volatile ::std::atomic_bool thread_shutdown;
   ::std::thread thread;
};

ConnectionHandler::ConnectionHandler()
     : thread_shutdown(false), thread(&this->start, this)
{
}

ConnectionHandler::~ConnectionHandler()
{
   thread_shutdown.store(true);
   thread.join();
}

void ConnectionHandler::start(ConnectionHandler * pThis){
   pThis->main();
}

int ConnectionHandler::addNewSocket(){
   ::std::lock_guard< ::std::mutex> lock(connectionList_mutex);
   ::std::cout << "test1" << ::std::endl;

   return 0;
}

int ConnectionHandler::main(){
   while(!thread_shutdown.load()){
      ::std::lock_guard< ::std::mutex> lock(connectionList_mutex);
      ::std::cout << "test2" << ::std::endl;
      ::std::this_thread::sleep_for(::std::chrono::milliseconds(100));

   }
   return 0;
}
于 2012-12-28T13:20:29.053 回答