std :: thread에 대한 OO 래퍼를 쓰고 있습니다. 다음은 코드의 단순화 된 버전입니다. 이 클래스의 문제점은 클래스가 즉시 파기 될 때 스레드에서 호출되기 때문에 오류가 발생할 수 있다는 것입니다 (순수 가상 메서드가 호출 됨).std :: thread 래퍼 클래스의 즉시 처리 처리
테스트 케이스가 아래쪽에 표시됩니다.
어떻게이 클래스를보다 안전하게 만들 수 있습니까? MyConThread가 MyConThread :: doWork에서 사용되는 멤버 변수를 가지고 있다면 더 복잡한 예제가 더 나 빠질 것입니다.
파생 된 클래스가 생성되기 전에 doWork가 호출 될 수있는 유사한 문제가 있음을 알고 있습니다.
#include <thread>
class ConThread {
public:
ConThread()
:t_ (doWorkInternal, this)
{}
~ConThread()
{
if (t_.joinable()) {
t_.join();//avoid a crash because std::thread will terminate the app if the thread is still running in it's destructor
}
}
std::thread& get() {return t_;};
protected:
virtual void doWork()=0;
private:
static void doWorkInternal (ConThread* t)
{
try {
t->doWork();
} catch (...)
{};
}
std::thread t_;
};
내가으로 실행하고 문제는 아래의 테스트 케이스이다 : 모든
class MyConThread: public ConThread
{
public:
long i=0;
protected:
void doWork() override
{
for (long j=0; j<1000000_ && requestedToTerminate_==false; j++)
{
++i;
}
}
};
TEST(MyConThreadTest, TestThatCanBeDestroyed)
{
MyConThread mct(); //<== crashes when being destroyed because thread calls t->doWork()
}
'에서 오는 requestedToTerminate_'는 무엇입니까? – Quentin
이것은 "OO"의 문제가 아닙니다. 기본 기능을위한 다른 API를 제공하는 래퍼를 작성하는 것입니다. – Hurkyl
그리고 덧붙여 말하자면 가상 함수는'std :: function' 메카니즘'std :: thread'가 사용하는 것보다 훨씬 덜 편리하고 유용하다고 생각합니다. – Hurkyl