서버 유형 응용 프로그램이 있으며 스레드가 완료되기 전에 스레드가 삭제되지 않도록하는 데 문제가 있습니다. 아래 코드는 내 서버를 대표합니다. 목록에서 죽은 스레드가 쌓이지 않도록하려면 정리가 필요합니다. 하복 (Havok)를 일으키는 원인이되는 shared_ptr의이 스레드가 완료되기 전에 삭제됩니다 'A'개체를 의미 스레드의 기능이 완료되면에서 파괴되는, 즉 때 스레드의 -다중 스레드 정리를 처리하는 가장 좋은 방법
using namespace std;
class A {
public:
void doSomethingThreaded(function<void()> cleanupFunction, function<bool()> getStopFlag) {
somethingThread = thread([cleanupFunction, getStopFlag, this]() {
doSomething(getStopFlag);
cleanupFunction();
});
}
private:
void doSomething(function<bool()> getStopFlag);
thread somethingThread;
...
}
class B {
public:
void runServer();
void stop() {
stopFlag = true;
waitForListToBeEmpty();
}
private:
void waitForListToBeEmpty() { ... };
void handleAccept(...) {
shared_ptr<A> newClient(new A());
{
unique_lock<mutex> lock(listMutex);
clientData.push_back(newClient);
}
newClient.doSomethingThreaded(bind(&B::cleanup, this, newClient), [this]() {
return stopFlag;
});
}
void cleanup(shared_ptr<A> data) {
unique_lock<mutex> lock(listMutex);
clientData.remove(data);
}
list<shared_ptr<A>> clientData;
mutex listMutex;
atomc<bool> stopFlag;
}
문제는 소멸자가 잘못된 순서로 실행하는 것이 보인다 소멸자가 호출됩니다.
즉 전화 정리 기능이에 대한 모든 참조 (즉는 A 객체) 제거, 그래서 다시 호출이 스레드의 소멸자 (이 스레드의 소멸자 포함) 소멸자를 호출 - OH NOES!
다른 스레드에서 기본 목록을 정리하거나 공유 포인터에 대해 시간 지연 삭제 기능을 사용하기 위해 주기적으로 사용되는 '제거 대상'목록을 유지 관리하는 것과 같은 대안을 살펴 보았습니다. 이들은 abit chunky처럼 보이고 경쟁 조건을 가질 수 있습니다.
누구든지 좋은 방법을 알고 있습니까? 나는 그것이 잘 작동하도록 리팩토링하는 쉬운 방법을 볼 수 없다.
몇 가지 예를 제공 할 수 있습니까? – 4pie0
@lizusek 예를 들어 무엇을 원하십니까? 여러 가지 해결책을 제안했습니다. –
사신 스레드를 만드는 방법의 예. 아무것도하지 않고 미해결의 thread에 합류 해 그 thread를 클린 업하는 thread. – 4pie0