xcode 互斥锁解锁异常失败
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14068816/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mutex unlock fails strangely
提问by Jonas Eschmann
I am playing around with some sockets, thread and mutexes. My question concerns threads and mutexes:
我在玩一些套接字、线程和互斥锁。我的问题涉及线程和互斥锁:
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();
}
}`
The main function is running in one thread, while the addNewSocket is called by another thread. The problem is, that when addNewSocket is called once (by the second thread), the next unlock by thread 1 (main) will fail with a strange "signal SIGABRT". I have worked two days on this now, but i did not manage to get it fixed, sadly. I hope you can help me.
main 函数在一个线程中运行,而 addNewSocket 由另一个线程调用。问题是,当 addNewSocket 被调用一次(由第二个线程)时,线程 1(主)的下一次解锁将失败,并出现一个奇怪的“信号 SIGABRT”。我现在已经为此工作了两天,但遗憾的是我没有设法解决它。我希望你能帮助我。
Edit: ConnectionHandler is a class, that has connectionList_mutex as a member.
编辑:ConnectionHandler 是一个类,它具有 connectionList_mutex 作为成员。
Edit: Sometimes i also get this error: "Assertion failed: (ec == 0), function unlock, file /SourceCache/libcxx/libcxx-65.1/src/mutex.cpp, line 44." but it occurs randomly.
编辑:有时我也会收到此错误:“断言失败:(ec == 0),函数解锁,文件 /SourceCache/libcxx/libcxx-65.1/src/mutex.cpp,第 44 行。” 但它是随机发生的。
Edit: This is the whole class (Reduced to a minimum, should be context independant to a certain degree, but crashes when i put it right after a client connected, and works if i put it right after the start:
编辑:这是整个课程(减少到最低限度,应该在一定程度上独立于上下文,但是当我在客户端连接后立即放置时会崩溃,如果我在开始后立即放置它会起作用:
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();
}
}
采纳答案by Omnifarious
My guess is that your ConnectionHandler
object is being destroyed somewhere. Also, you have defined ConnectionHandler::start
in a silly way.
我的猜测是您的ConnectionHandler
对象正在某处被销毁。此外,您ConnectionHandler::start
以愚蠢的方式定义了。
First, ConnectionHandler::start
should be defined this way:
首先,ConnectionHandler::start
应该这样定义:
void ConnectionHandler::start(ConnectionHandler * pThis){
pThis->main();
}
The C++11 ::std::thread
class is perfectly capable of preserving the type of the function argument so there is no need to resort to void *
.
C++11::std::thread
类完全能够保留函数参数的类型,因此无需求助于void *
.
Secondly, add in this code:
其次,添加以下代码:
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();
}
And change the constructor to read:
并将构造函数更改为:
ConnectionHandler::ConnectionHandler(){
const void * const meptr = this;
::std::cout << "ConnectionHandler being created at " << meptr << ::std::endl;
std::thread t(&this->start, this);
t.detach();
}
This will show you when the ConnectionHandler
object is being destroyed. And my guess is that your code is destroying it while your detached thread is still running.
这将显示ConnectionHandler
对象何时被销毁。我的猜测是,当您的分离线程仍在运行时,您的代码正在破坏它。
The meptr
thing is because operator <<
has an overload for void *
that prints out the pointer value. Printing out the pointer value for this
will allow you to match up calls to the constructor and destructor if you're creating multiple ConnectionHandler
objects.
该meptr
事情是因为operator <<
有过载void *
,打印出来的指针值。this
如果您正在创建多个ConnectionHandler
对象,打印出指针值将允许您匹配对构造函数和析构函数的调用。
Edit:Since it turned out I was correct, here is how I would recommend you write the play ConnectionHandler class:
编辑:事实证明我是正确的,以下是我建议您编写 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;
}