【问题标题】:C++ pthread hand over object to threadC++ pthread 将对象移交给线程
【发布时间】:2021-09-19 01:49:35
【问题描述】:

我认为通过我的代码,我将对象的地址交给了线程。 但是我无法直接访问该对象(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);

}

【问题讨论】:

  • 您不使用std::thread的原因是什么?
  • ot:您的 barometerThread 缺少 return,这是未定义的行为
  • 错误似乎来自不同的代码。错误消息抱怨 args.getID() 但在您的代码中您有正确的 dev.getID()
  • 哦哦。我知道了。请发布实际存在您问题的错误的代码代码。 cmets中的代码很容易被忽略,不会产生编译错误
  • @user2864740 OP 正在谈论他们在正文中制作的副本

标签: c++ pthreads


【解决方案1】:

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

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

通常应该首选正确的 C++ 类型转换 (static_cast/dynamic_cast),尽管我们正在处理 void*,无论如何,确保类型转换正确,c - 风格的演员是“好的”。

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

【讨论】:

  • 您的答案也正确且有效。不幸的是,我不能将两个答案标记为“已解决”,唯一的区别是,我必须使用“->”运算符来访问属性/方法,而不是“。”点。
【解决方案2】:

您可以通过将转换行更改为:

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

所以现在它将是对 Sensors 对象的引用而不是副本。

假设 getID() 是一个 Sensors 类方法,您可以这样做:

cout << dev.getID();

转换后。

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

【讨论】:

    猜你喜欢
    • 2014-12-24
    • 2011-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-15
    相关资源
    最近更新 更多