简体   繁体   中英

std::jthread runs a member function from another member function

Here is my code:

#include <iostream>
#include <zconf.h>
#include <thread>

class JT {
public:
    std::jthread j1;

    JT() {
        j1 = std::jthread(&JT::init, this, std::stop_token());
    }

    void init(std::stop_token st={}) {

        while (!st.stop_requested()) {
            std::cout << "Hello" << std::endl;
            sleep(1);
        }
        std::cout << "Bye" << std::endl;
    }
};

void init_2(std::stop_token st = {}) {
    while (!st.stop_requested()) {
        std::cout << "Hello 2" << std::endl;
        sleep(1);
    }
    std::cout << "Bye 2" << std::endl;
}

int main() {
    std::cout << "Start" << std::endl;
    JT *jt = new JT();
    std::jthread j2(init_2);
    sleep(5);
    std::cout << "Finish" << std::endl;
}

Here is the output:

Start
Hello
Hello 2
Hello
Hello 2
Hello
Hello 2
Hello
Hello 2
Hello
Hello 2
Finish
Bye 2
Hello

The problem is I could get Bye 2 message but not Bye message.

I know the passed stop_token variable results in this problem but I do not know how to pass it to a member function inside another member function.

If I'm understanding the problem correctly (my understanding being that for std::jthread(&JT::init, this) jthread wants to call JT::init(std::stop_token st, this) , which isn't going to work), you probably want to use std::bind_front to give it a Callable that works. eg

    JT() {
    j1 = std::jthread(std::bind_front(&JT::init, this));
}

According to the useful comments, I have rewritten the class code as below:

class JT {
public:
    std::jthread j1;

    JT() {
        j1 = std::jthread(&JT::init, this);
    }

    void init() {
        auto st = j1.get_stop_token();
        while (!st.stop_requested()) {
            std::cout << "Hello" << std::endl;
            sleep(1);
        }
        std::cout << "Bye" << std::endl;
    }
};

You must get the stop_token on the fly through auto st = j1.get_stop_token(); .

And the revised main function:

int main() {
    std::cout << "Start" << std::endl;
    JT *jt = new JT();
//    auto jt = std::make_unique<JT>();
    std::jthread j2(init_2);
    sleep(5);
    std::cout << "Finish" << std::endl;
    delete jt;
}

You need to delete the class object directly or use RAII (like smart pointers).

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