Всем привет. Есть некоторое приложение (еще недопиленное), порождается некоторое кол-во потоков. Некоторые потоки идут на блокирующие операции (чтение с консоли, сокеты). В связи с этим вопрос возникает - а как это хозяйство завершить?
- Делать для всех потоков join() - потоки заблокированы и хз когда освободятся, отметаем.
- Сгодится что-то вроде terminate(), но без всякого - «аварийный останов, корки скинуты на диск». exit() - начинает разрушать софтину деликатно - с разрушением ГВ, а потоки-то живут, в общем опять может случиться какой-нибудь «сег фолт».
- Сделать потоком detach(), опять же - когда софтина начнет завершаться, потоки живут, и потом - должны ведь и библиотеки отваливаться начать. Я вообще никогда не видел описания процесса отстегивания либ при завершении - сначала перестает выделяться процессорное время всем тредам, а потом отстегивается, или как-то иначе.
- Сделать все глобальные объекты неудаляемыми, т.е. вначале main() делать new, и пусть живут «вечно». Но опять же вопрос с моментом отстегивания либ - до или после момента, когда потокам перестает выделяться процессорное время. Это если либы so’шки, а если статические, то вообще без вариантов - никакой надежды на «либы переживут треды» нет.
Понятно, что как-то в любом случае завершится, но хочется без всяких жалоб в консоль на мою криворукость.
Минимальный пример смоделированный на коленках (понятно, что момент выгрузки либ он не затрагивает), который падаете с сег фолтом:
#include <thread>
#include <chrono>
using namespace std;
struct Q {
int *i;
Q() {i = new int;}
~Q() {delete i; i = 0; this_thread::sleep_for(5s);}
};
int *get() {
static Q q;
return q.i;
}
void f() {
this_thread::sleep_for(2s);
*get() = 5;
}
int main() {
get();
thread t(f);
t.detach();
}