簡體   English   中英

如何將 jthread stop_token 傳遞給函子?

[英]How to pass jthread stop_token to functor?

我正在嘗試使用新的 jthreads 並啟動了一個std::jthread ,在其中調用了 operator(),但我無法讓它停止。 我想通過將其作為函數對象調用來創建線程。

my_thrd = std::make_shared<std::jthread>(&Test::operator(), &test);

如果我的 Test 類的operater()編寫如下,它將編譯:

void Test::operator()()
{
    using namespace std::literals;
    
    while (!token.stop_requested()) {
        std::cout << "Working ...\n" << std::flush;

        std::this_thread::sleep_for(5s);
    }   
    
    close_connection();
}   

但由於它沒有停止,我想我需要以某種方式將std::stop_token傳遞給class Test ,就像這樣。

void Test::operator()(std::stop_token token) { ... }

但這不能編譯。 我也確實更改了標題。

/usr/lib/gcc/x86_64-pc-linux-gnu/10.3.0/include/g++-v10/thread: 在實例化 'static std::thread std::jthread::_S_create(std::stop_source&, _Callable&& , _Args&& ...) [with _Callable = void (Test:: )(std::stop_token); _Args = {Test }]': /usr/lib/gcc/x86_64-pc-linux-gnu/10.3.0/include/g++-v10/thread:450:28: 來自'std::jthread::jthread( _Callable&&, _Args&& ...) [with _Callable = void (Test:: )(std::stop_token); _Args = {測試}; = void]' /usr/lib/gcc/x86_64-pc-linux-gnu/10.3.0/include/g++-v10/bits/stl_construct.h:97:14: 來自'constexpr decltype (::new(void) *(0)) _Tp) std::construct_at(_Tp*, _Args&& ...) [與 _Tp = std::jthread; _Args = {void (Test:: )(std::stop_token), Test }; decltype (::new(void*(0)) _Tp) = std::jthread*]' /usr/lib/gcc/x86_64-pc-linux-gnu/10.3.0/include/g++-v10/bits/alloc_traits .h:514:4: 來自 'static constexpr void std::allocator_traitsstd::allocator<_CharT >::construct(std::allocator_traitsstd::allocator<_CharT >::allocator_type&, _Up*, _Args&& ...) [ _Up = std::jthread; _Args = {void (Test:: )(std::stop_token), Test }; _Tp = std::jthread; std::allocator_traitsstd::allocator<_CharT >::allocator_type = std::allocatorstd::jthread]'

想法?

您可以使用std::bind&test綁定到&Test::operator() ,然后使用std::placeholders::_1為未綁定的std::stop_token保留一個位置:

struct Test {
  void operator()(std::stop_token token) {
    using namespace std::literals;
    while (!token.stop_requested()) {
      std::cout << "Working ...\n" << std::flush;
      std::this_thread::sleep_for(5s);
    }
  }
};

int main() {
  Test test;
  auto my_thrd = std::make_shared<std::jthread>(
    std::bind(&Test::operator(), &test, std::placeholders::_1));
}

演示。

正如@Nicol Bolas 所評論的,我們也可以使用 C++20std::bind_front來做到這一點,它比std::bind更輕量和直觀:

auto my_thrd = std::make_shared<std::jthread>(
    std::bind_front(&Test::operator(), &test));

一個簡單有效的解決方案是使用 lambda:

auto my_thrd = std::make_shared<std::jthread>(
  [&test] (std::stop_token token) { test(token); });

並節省額外的費用和圖書館設施

演示

jthread (或thread ,就此而言)接受任何可調用對象。 這包括任何帶有operator()東西,比如... Test

默認是按值傳遞; 使用std::ref通過引用傳遞,但請注意,在這種情況下,您需要確保被引用的對象比線程存活的時間更長。

所以這只是:

auto my_thrd = std::make_shared<std::jthread>(test);

或(像原始代碼一樣通過引用傳遞):

auto my_thrd = std::make_shared<std::jthread>(std::ref(test));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM