我正尝试使用C++ 11中的线程库编写多线程软件。在互联网上发现的一些基本教程可以按预期进行编译和运行。但是我自己的应用程序分为类,总是抛出异常。如何避免在C++ 11中出现<thread>引发的异常?
任何人都可以告诉我应该修复哪部分代码吗?
$ 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的科学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;
}
= main.cxx =
#include "BaseInterface.h"
int main()
{
BaseInterface interface;
interface.Open();
interface.Close();
return 0;
}
感谢您的详细评论。我还在寻找不需要DoReceive和空指针检查的标准技术。所以你的建议使我的代码变得理想。 'fThread = new std :: thread(Receive,this);'没有编译。所以我删除了DoReceive(),并将Remove()更改为operator()()根据另一个线程http://stackoverflow.com/questions/9189989/stdthread-start-thread-on-this-from-within-the-类本身 – 2013-03-07 09:59:16
我在一个错误的位置使用join()并准备好DoReceive的原因是,我的软件是使用另一个线程库从旧C++代码更新的。在那个库中,join是在这个错误的位置上工作的,C++ 11像线程构造函数不被支持。 – 2013-03-07 10:08:20