简体   繁体   中英

C++ pthread hand over object to thread

I think with my code, I hand over the address of the object to the thread. However I cannot access the object directly (args.getTerminationStatus).

Unfortunately I only make a copy of that passed object and therefore changes of attributes take no effect (the while loop ist running forever, even thought the attribute behind getTerminationStatus() has changed outside). Would be nice if you have some ideas. Thanks in advance.

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);

}

You do not need to make a copy. As you are absolutely certain that the void* you pass to the function is pointing to a Sensor you can cast the pointer:

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

Usually a proper C++ cast ( static_cast / dynamic_cast ) should be prefered, though as we are dealing with a void* and anyhow it is all up to you to make sure that the cast is correct, a c-style cast is "ok".

Note that you are missing the return in the function but it must return a void* . If it does not you invoke undefined behavior. Also there is std::thread which keeps you away from such void* anachronisms.

You can avoid the copy by changing the conversion line to:

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

so that now it will be a reference to a Sensors object rather than a copy.

Assuming getID() is a Sensors class method you can then do:

cout << dev.getID();

after you've converted it.

If you haven't considered it yet, using std::thread would make life a bit easier here (since it accepts std::function s which you can bind arbitrary typed data to). Another thing to keep in mind is that the Sensors class instance will be accessed from two threads, so make sure barometer.finish() and dev.getTerminationStatus() are both thread safe!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM