Потоковая функция-член, получающая неверное значение из переменной-члена

#c #c 11

#c #c 11

Вопрос:

Это должен быть простой код, но он не работает должным образом.
Функция-член, выполняемая как поток, получает неверное значение из переменной-члена.

 #include <chrono>
#include <thread>
#include <vector>
#include <iostream>



class Worker
{
    private:
        const int workerID;
        
        
    public:
        Worker( int id ) : workerID( id )
        {
            std::cout << "Constructor: " << workerID << std::endl;
            std::this_thread::sleep_for( std::chrono::milliseconds( 500 ));

            std::thread thread( amp;Worker::Run, this );
            thread.detach( );
        }
        
        
    private:
        void Run( )
        {
            std::this_thread::sleep_for( std::chrono::milliseconds( 1000 ));
            std::cout << "Worker: " << workerID << std::endl;
        }
};



int main()
{
    std::vector<Worker> workers;
    
    workers.emplace_back( 1 );
    workers.emplace_back( 2 );
    
    std::this_thread::sleep_for( std::chrono::milliseconds( 2000 ));
    return 0;
}
  

Ожидаемый результат был:

 Constructor: 1
Constructor: 2
Worker: 1
Worker: 2
  

Но вместо этого я получаю:

 Constructor: 1
Constructor: 2
Worker: 0
Worker: 2
  

Может кто-нибудь просветить меня, почему он ведет себя таким образом?
Что я делаю не так?
Спасибо!

Комментарии:

1. Ваше второе место обратно перераспределило вектор, который перемещает класс, и, таким образом, аннулировало указатель this в потоке

2. Теперь я это вижу. Спасибо!

3. Примечание сбоку: вы обнаружите, что сохранение thread s и join редактирование их перед выходом значительно стабильнее, чем detach редактирование, и молитесь, чтобы вы ждали достаточно долго, когда все усложнится.

4. Ваш код не синхронизирует доступ к переменной-члену. Это формальное условие гонки в C , и оно заставляет вашу программу выполнять UB. Не синхронизируйте только с помощью sleep в C . Это незаконно.