带有此指针的线程安全工作线程

问题描述

我正在使用 std::thread 对象通过使用线程安全队列中的值来执行网络访问。可以将类的 this 指针传递给线程吗? modbus 队列是一个线程安全的对象,所以这不是问题。

我只是担心指针访问,因为指针不是线程安全的。我知道我可以只传递队列对象,但这只是出于好奇。

我现在可能在读取 threadCancel bool 对象没有被销毁的时候,但在那之后,它可能是未定义的。

在析构函数中锁定互斥量是否是好的行为?

std::atomic_bool modbusThreadRunning = false;
std::atomic_bool cancelThread = false;


void modbusWorkerThread(DataAcquisition* this_p) {
    //Reference to a thread safe object
    if(cancelThread){
        modbusThreadRunning = false;
        return;
    }
    std::scoped_lock lock(this_p->destroyLocker);
    auto& queue = this_p->getModbusQueue();
    
    while (this_p->getModbusQueue().count() > 0) {
        //Access values of queue and modify it
        //Without the class getting destroyed
    }
    modbusThreadRunning == false;
}


class DataAcquisition{
    std::thread* modbusThread;
    std::mutex destroyLocker;
    ts_queue<int> queue;
    void startModbusThread() {
        if (modbusThreadRunning == false)
        {
            modbusThreadRunning = true;
            modbusThread = new std::thread (modbusWorkerThread,this);
            modbusThread->detach();
        }
    }

    ts_queue<int>& getModbusQueue(){ return queue; } 

    ~DataAcquisition(){ cancelThread = true; destroyLocker.lock(); }
}

解决方法

您还没有展示完整的、自包含的代码来展示您的多个执行线程如何工作的全部内容,因此无法根据展示的代码来分析其在新执行线程中使用指针的情况是否正确未定义的行为与否。但是:可以权威地回答您的一般问题——当以这种方式将 this 指针传递给新的执行线程时,与任何其他指针相比,它没有任何独特或特殊之处。

如果将指向某个对象的普通指针传递给新的执行线程,则只要引用的对象存在,该指针就保持有效。在底层对象被销毁后,访问指针变为未定义行为。

同样的事情适用于 this 指针。在它的对象被销毁后,以任何方式访问指针,无论是访问其成员还是方法,都会成为未定义的行为。

您需要确保在其余代码中,以某种形式或方式,在底层对象被销毁后,执行线程永远不会访问传入的指针。