简体   繁体   中英

"const std::stop_token&" or just "std::stop_token" as parameter for thread function?

Since clang-tidy was complaining about "The parameter 'stop_token' is copied for each invocation but only used as a const reference; consider making it a const reference" I was asking myself the question, why every example I find about std::jthread/stop_token takes the stop_token by value, but I did not find any explanation for it.

So, why take the stop_token by value?

1) void f(std::stop_token){};
2) void f(const std::stop_token&){};

Does it really matter when you can assume that the stop_token is the one generated by std::jthread?

edit: This is asked purely out of curiosity and to not ignore a clang-tidy warning "just because".

As per cppref ,

Creates new jthread object and associates it with a thread of execution. The new thread of execution starts executing

std::invoke(std::move(f_copy), get_stop_token(), std::move(args_copy)...) , ...

And the return type ofstd::jthread::get_stop_token is std::stop_token .

So, if your f is only used to construct a std::jthread , I believe it's totally ok to be with a const std::stop_token& as its first parameter. There's no lifetime issue.

But if you want to use your f in other places, std::thread for example, there may be a problem.

void f(const std::stop_token&) {}
{
    std::stop_source ssrc;
    std::stop_token stk{ssrc.get_token()};
    std::thread t{f, std::ref(stk)};
}

When stk gets destroyed, the reference is dangled.


In most cases, you should pass by value.

Because copying std::stop_token and std::stop_source is relative cheap.
Also, since std::token is usually stored in a lambda and/or used in another thread, passing by value can avoid lifetime issues.

There're also some cases where you could pass by reference.

Since it's not that cheap compared to raw pointers. It'll be more efficient to pass by reference if you can guarantee the lifetime.

For example, std::stop_callback 's constructor , because it'll copy std::stop_token inside, pass by reference will be better.

template<class C>
explicit stop_callback( const std::stop_token& st, C&& cb ) noexcept(/*see below*/);

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