Я написал небольшое приложение для демонстрации проблемы, это не очень, но он выполняет эту работу.C++ 11: Segfault с std :: thread и лямбда-функцией
#include <functional>
#include <iostream>
#include <mutex>
#include <queue>
#include <thread>
class A {
public:
A() : thread_(), tasks_(), mutex_(), a_(99999) {}
void Start() {
thread_ = std::thread([this]() { Run(); });
}
private:
using Task = std::function<void()>;
public:
void AddTask(const Task& task) {
std::lock_guard<std::mutex> lock(mutex_);
tasks_.push(task);
}
bool Empty() {
std::lock_guard<std::mutex> lock(mutex_);
const bool empty = tasks_.empty();
return empty;
}
Task GetTask() {
std::lock_guard<std::mutex> lock(mutex_);
const auto& task = tasks_.front();
tasks_.pop();
return task;
}
int GetInt() { return a_; }
void Join() { thread_.join(); }
private:
void Run() {
while (Empty());
(GetTask())();
}
std::thread thread_;
std::queue<Task> tasks_;
std::mutex mutex_;
int a_;
};
template <class Base>
class B : public Base {
public:
using Base::Base;
void Start() {
Base::Start();
std::cout << "A: " << this << std::endl;
Base::AddTask([this]() { std::cout << "T: " << this << std::endl; Do(); });
}
void Do() {
std::cout << "Do: " << this << std::endl;
std::cout << "GetInt: " << Base::GetInt() << std::endl;
}
};
int main() {
B<A> app;
app.Start();
app.Join();
}
лязг ++ -std = C++ 11 -lpthread test_a.cpp
A: 0x7ffeb521f4e8
T: 0x21ee540
Do: 0x21ee540
GetInt: 0
Обратите внимание на изменение в 'это', а значение 0 для 'GetInt'.
Я действительно потерял здесь ... Любая помощь будет принята с благодарностью,
Спасибо.
Я смотрел на это немного назад, рад видеть, что вы заметили, что это не относится к tcmalloc. Когда я посмотрел, я нашел «причину» проблемы. Последовательность: 'app.Start()', основной поток добавляет задачу, основной поток достигает конца области и существ, разрушающих 'приложение'. Часть 'B' разрушается, блоки« A »в потоке. Thread поднимает задачу, и вы получаете неопределенное поведение, когда оно вызывает 'B :: Do', потому что часть' B' больше не существует. Тем не менее, я не опубликовал ответ, потому что я действительно озадачен тем, почему значение 'this' изменяется. :) Я постараюсь понять это завтра, если никто не выяснит это. – GManNickG
(Я имею в виду, я мог бы просто заключить: «это неопределенное поведение, что-то происходит, не делайте этого». Но я хотел бы знать, почему «это» когда-либо изменится в практических реализациях.) – GManNickG
Спасибо GManNickG. Не могли бы вы подтвердить, что я исправил проблему, которую вы определили? Если это так, я должен упомянуть, что выход программы не изменяется. – Nick