У меня есть серверное приложение, и у меня есть проблема с тем, что потоки не удаляются до их завершения. Кодекс ниже в значительной степени представляет собой мой сервер; очистка требуется для предотвращения накопления мертвых потоков в списке.Лучший способ обработки многопоточной очистки
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;
}
Проблема, кажется, что деструкторы работают в неправильном порядке - т.е. shared_ptr разрушается в том, когда функция потока завершается, то есть «A» объект удаляется до завершения потока, в результате чего Havok, когда нити вызывается деструктор.
т.е. Вызов функции очистки Все ссылки на это (то есть Л объект) удаляется, так называют деструктор (включая деструктор этого потока) вызова деструктора эту нить снова - ОН голосующие!
Я рассмотрел альтернативы, такие как сохранение списка «для удаления», который периодически используется для очистки основного списка другим потоком или с помощью функции удаления по времени для общих указателей, но обе они кажутся непримиримыми и могут иметь условия гонки.
Кто-нибудь знает, как это сделать? Я не вижу простой способ рефакторинга, чтобы он работал нормально.
Вы можете указать пример? – 4pie0
@lizusek Пример для чего? Я предложил несколько разных решений. –
пример того, как создать резьбу для жгута; поток, который ничего не делает, кроме как присоединиться к любым выдающимся потокам, чтобы очистить их после них. – 4pie0