如何避免 <thread> C++11 中引发的异常?
How can I avoid an exception thrown by <thread> in C++11?
我正在尝试使用c++ 11中的线程库编写多线程软件。在互联网上找到的一些基本教程可以按预期编译和运行。但是我自己的应用程序总是会抛出一个异常。
谁能告诉我代码的哪一部分应该修复,请?
$ clang++ -std=c++11 -stdlib=libc++ BaseInterface.cxx -c -o BaseInterface.o
$ clang++ -std=c++11 -stdlib=libc++ SocketReceiver.cxx -c -o SocketReceiver.o
$ clang++ -std=c++11 -stdlib=libc++ main.cxx -c -o main.o
$ clang++ -std=c++11 -stdlib=libc++ main.o BaseInterface.o SocketReceiver.o -o main
$ gdb main
(gdb) run
Starting program: /Users/oxon/test/main
Reading symbols for shared libraries ++............................ done
libc++abi.dylib: terminate called throwing an exception
Program received signal SIGABRT, Aborted.
[Switching to process 859 thread 0x40b]
0x00007fff88df8212 in __pthread_kill ()
(gdb) bt
#0 0x00007fff88df8212 in __pthread_kill ()
#1 0x00007fff8bc85af4 in pthread_kill ()
#2 0x00007fff8bcc9dce in abort ()
#3 0x00007fff894d3a17 in abort_message ()
#4 0x00007fff894d13c6 in default_terminate ()
#5 0x00007fff89874887 in _objc_terminate ()
#6 0x00007fff894d13f5 in safe_handler_caller ()
#7 0x00007fff894d1450 in std::terminate ()
#8 0x00007fff894d25b7 in __cxa_throw ()
#9 0x00007fff8a9ba3b9 in std::__1::thread::join ()
#10 0x0000000100000cf0 in SocketReceiver::Receive ()
#11 0x0000000100000c6d in SocketReceiver::DoReceive ()
#12 0x0000000100001593 in _ZNSt3__114__thread_proxyINS_5tupleIJPFPvS2_ES2_EEEEES2_S2_ ()
#13 0x00007fff8bc84742 in _pthread_start ()
#14 0x00007fff8bc71181 in thread_start ()
这是在OS X 10.8上的结果。使用GCC 4.4的Scientific Linux 6也给出了类似的结果。
= BaseInterface.h =
#ifndef BASE_INTERFACE_H
#define BASE_INTERFACE_H
#include "SocketReceiver.h"
class BaseInterface
{
private:
SocketReceiver* fReceiver;
public:
BaseInterface();
virtual ~BaseInterface();
virtual void Close();
virtual void Open();
;
#endif
= BaseInterface。cxx =
#include <iostream>
#include <string.h>
#include <unistd.h>
#include "BaseInterface.h"
BaseInterface::BaseInterface()
{
fReceiver = new SocketReceiver(this);
}
//______________________________________________________________________________
BaseInterface::~BaseInterface()
{
Close();
delete fReceiver;
fReceiver = 0;
}
//______________________________________________________________________________
void BaseInterface::Close()
{
fReceiver->Stop();
usleep(10000);
while(fReceiver->IsRunning()){
usleep(10000);
} // while
}
//______________________________________________________________________________
void BaseInterface::Open()
{
fReceiver->Start();
}
= SocketReceiver.h =
#ifndef SOCKET_RECEIVER_H
#define SOCKET_RECEIVER_H
#include <thread>
#include <mutex>
class BaseInterface;
class SocketReceiver
{
private:
BaseInterface* fInterface;
bool fIsRunning;
std::mutex fMutex;
bool fStop;
std::thread* fThread;
public:
SocketReceiver(BaseInterface* interface = 0);
virtual ~SocketReceiver();
bool IsRunning() const {return fThread ? true : false;}
static void* DoReceive(void* arg);
void Receive();
void Start();
void Stop();
};
#endif
= SocketReceiver。cxx =
#include <iostream>
#include <thread>
#include <unistd.h>
#include "BaseInterface.h"
#include "SocketReceiver.h"
SocketReceiver::SocketReceiver(BaseInterface* interface)
{
fInterface = interface;
fStop = true;
fThread = 0;
}
//______________________________________________________________________________
SocketReceiver::~SocketReceiver()
{
}
//______________________________________________________________________________
void* SocketReceiver::DoReceive(void* arg)
{
SocketReceiver* receiver = (SocketReceiver*)arg;
receiver->Receive();
return 0;
}
//______________________________________________________________________________
void SocketReceiver::Receive()
{
while(not fStop){
fMutex.lock();
usleep(10000);
fMutex.unlock();
} // while
fThread->join();
delete fThread;
fThread = 0;
}
//______________________________________________________________________________
void SocketReceiver::Start()
{
fStop = false;
fThread = new std::thread(DoReceive, (void*)this);
}
//______________________________________________________________________________
void SocketReceiver::Stop()
{
fStop = true;
}
=主要。cxx =
#include "BaseInterface.h"
int main()
{
BaseInterface interface;
interface.Open();
interface.Close();
return 0;
}
您正在连接线程本身。在父线程中调用join
,就像在SocketReceiver::Stop
中一样。
当join
被调用时,它清理底层数据。如果你在正在运行的线程中调用它,那么当线程仍然需要它时,该数据将被删除。
如果std::thread
运行的函数通过异常退出,那么std::terminate
将被调用。
std::thread::join()
被指定为抛出std::system_error
和错误码resource_deadlock_would_occur
,如果join()
在同一个线程中被调用,即一个线程不能加入自己。因此,您尝试使线程连接本身会导致异常,从而终止进程。一个线程不能加入自己,加入被定义为"等待线程完成",所以显然不能由线程自己完成,它会阻止等待自己完成,这不能发生,直到调用join()
完成,这不能发生,直到线程完成,这不能发生,直到调用join()
完成…你知道这是怎么回事吗?
你为什么要这样做?
fThread = new std::thread(DoReceive, (void*)this);
std::thread
不是pthread_create
,你不需要传递void*
,只要去掉DoReceive
并调用:
fThread = new std::thread(&SocketReceiver::Receive, this);
为什么你的std::thread
与new
分配?这也不是必要的,你可以使用std::thread
成员并使用joinable()
来检查它是否活跃,而不是检查指针是否为非空。
- 处理多个异常集合的C++方法
- 我在c++代码中生成了一个运行时#3异常
- 孤立代码块在结构中引发异常
- C++中的赋值发生,尽管右侧出现异常
- 从构造函数抛出异常时如何克服内存泄漏
- 异常属于C++中的线程还是进程
- 当类定义不可见时捕获异常
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- 为什么异常不退出程序?
- EASTL矢量<向量<int>>连续的
- 为什么我应该在异常处理中使用std::cerr而不是std::cout
- 如何修复链表类实现的未处理异常0xDDDDDDDD
- 关于:C++中异常对象的范围:为什么我没有得到副本?
- 是什么导致了Unity 3D中的"错误线程异常"?
- 如何将strftime中的格式错误作为异常捕获
- 创建具有 new in 函数和"this is nullptr"异常的对象
- 尝试使用智能指针时引发异常
- 函数如何通知用户它基于函数原型抛出异常?
- 是否值得降低我的代码的可读性,以便在出现内存不足错误时提供异常安全性?
- 当我使用 C++ 中的 C# dll 来使用 Selenium 时,存在异常处理问题