C++ pthread 将对象交给线程

C++ pthread hand over object to thread

我想用我的代码,我把对象的地址交给了线程。 但是我无法直接访问该对象 (args.getTerminationStatus)。

不幸的是,我只复制了那个传递的对象,因此属性的更改不起作用(while 循环 运行 永远存在,即使 getTerminationStatus() 后面的属性已经在外部更改)。如果您有一些想法,那就太好了。提前致谢。

int main(){

    Sensors barometer(1, "Barometer", 0); //ID, Description, Value

    pthread_t t1;
    int ret1;
    ret1 = pthread_create(&t1, NULL, &barometerThread, &barometer); //Hand over object to thread
    if(ret1 != 0){
        cout << "Error: Thread 1 (Luftdruckmesser) konnte nicht erstellt werden." << endl;
        return 1;
    }

    sleep(10);
    barometer.finish(); // Sets TerminationStatus to true
void *barometerThread(void *args){

    Sensors dev = *(Sensors *) (args); // I think this is just a copy of that passed object

    cout << "Luftdruck-Thread gestartet. Device-ID: " << dev.getID() << " Descr.: " << dev.getDescription() << " Value: " << dev.getValue() << endl;

    while (!dev.getTerminationStatus()){
        cout << "Still in loop: " << dev.getTerminationStatus() << endl;
        sleep(1);
    }

    pthread_exit(0);

}

您可以通过将转换行更改为来避免复制:

Sensors& dev = *(Sensors *) (args);

现在它将成为对 Sensors 对象的引用,而不是副本。

假设 getID() 是一个 Sensors class 方法然后你可以这样做:

cout << dev.getID();

转换后。

如果您还没有考虑过,使用 std::thread 会让这里的生活更轻松一些(因为它接受 std::function,您可以将任意类型的数据绑定到)。要记住的另一件事是 Sensors class 实例将从两个线程访问,因此请确保 barometer.finish()dev.getTerminationStatus() 都是线程安全的!

您不需要复印。由于您绝对确定传递给函数的 void* 指向 Sensor ,因此您可以转换指针:

void *barometerThread(void *args){
    Sensor* dev_ptr = (Sensor*)args;
  
    // ....

通常应该首选适当的 C++ 转换 (static_cast/dynamic_cast),尽管我们正在处理 void*,无论如何这完全取决于您来确保演员表是正确的,C 风格的演员表是“好的”。

请注意,您在函数中缺少 return,但它必须 return 和 void*。如果没有,您将调用未定义的行为。还有 std::thread 让你远离这样的 void* 时代错误。