У меня есть этот объект, содержащий поток. Я хочу, чтобы судьба объекта и судьба нити были едины в одном. Поэтому конструктор создает поток (с pthread_create
), и деструктор выполняет действия, чтобы поток возвращался в течение разумного промежутка времени и затем соединял поток. Это работает нормально, пока я не создаю экземпляр одного из этих объектов со статической продолжительностью хранения. Если я создаю экземпляр одного из этих объектов в глобальном пространстве или пространстве имен или в статическом классе, программа компилирует fine (gcc 4.8.1), но сразу же переходит в режим работы. С заявлениями печати я определил, что основной поток даже не вводит main() перед segfault. Любые идеи?
Обновление: также добавлен оператор печати в первую строку конструктора (поэтому до вызова pthread_create
), и даже это не печатается перед segfault, но конструктор действительно использует список инициализации, поэтому возможно что-то там вызывает его?
Вот конструктор:
worker::worker(size_t buffer_size):
m_head(nullptr),m_tail(nullptr),
m_buffer_A(operator new(buffer_size)),
m_buffer_B(operator new(buffer_size)),
m_next(m_buffer_A),
m_buffer_size(buffer_size),
m_pause_gate(true),
m_worker_thread([this]()->void{ thread_func(); }),
m_running(true)
{
print("this wont get printed b4 segfault");
scoped_lock lock(worker_lock);
m_worker_thread.start();
all_workers.push_back(this);
}
И деструктор:
worker::~worker()
{
{
scoped_lock lock(worker_lock);
auto w=all_workers.begin();
while(w!=all_workers.end())
{
if(*w==this)
{
break;
}
++w;
}
all_workers.erase(w);
}
{
scoped_lock lock(m_lock);
m_running=false;
}
m_sem.release();
m_pause_gate.open();
m_worker_thread.join();
operator delete(m_buffer_A);
operator delete(m_buffer_B);
}
Обновление 2:
Хорошо, я понял это. Моя функция печати является атомарной, а также защищает cout
с мьютексом области внешнего пространства имен, определенным в другом месте. Я изменился до простого cout
, и он был напечатан в начале ctor. По-видимому, ни один из этих мьютексов продолжительности статического хранения не инициализируется, прежде чем что-то пытается получить к ним доступ. Так что, вероятно, это ответ Кейси.
Я просто не буду беспокоиться о сложных объектах и продолжительности статического хранения. В любом случае это не имеет большого значения.