Namespaces
Variants

std::jthread:: jthread

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
jthread ( ) noexcept ;
(1) (C++20 이후)
jthread ( jthread && other ) noexcept ;
(2) (C++20 이후)
template < class F, class ... Args >
explicit jthread ( F && f, Args && ... args ) ;
(3) (C++20 이후)
jthread ( const jthread & ) = delete ;
(4) (C++20 이후)

새로운 std::jthread 객체를 생성합니다.

1) 스레드를 나타내지 않는 새로운 std::jthread 객체를 생성합니다.
2) 이동 생성자. std::jthread 객체를 other 가 나타내던 실행 스레드를 나타내도록 생성합니다. 이 호출 이후 other 는 더 이상 실행 스레드를 나타내지 않습니다.
3) 새로운 std::jthread 객체를 생성하고 실행 스레드와 연결합니다.

새로운 실행 스레드는 다음을 실행하기 시작합니다:

std:: invoke ( decay-copy ( std:: forward < F > ( f ) ) , get_stop_token ( ) ,
decay-copy ( std:: forward < Args > ( args ) ) ... )
(C++23 이전)

std:: invoke ( auto ( std:: forward < F > ( f ) ) , get_stop_token ( ) ,
auto ( std:: forward < Args > ( args ) ) ... )

(C++23 이후)

위의 표현식이 유효한 경우에 실행되며, 그렇지 않으면 다음을 실행하기 시작합니다:

std:: invoke ( decay-copy ( std:: forward < F > ( f ) ) ,
decay-copy ( std:: forward < Args > ( args ) ) ... )
.
(C++23 이전)

std:: invoke ( auto ( std:: forward < F > ( f ) ) ,
auto ( std:: forward < Args > ( args ) ) ... )
.

(C++23 이후)
decay-copy 호출이 평가됩니다 (until C++23) auto 에 의해 생성된 값들이 구체화됩니다 (since C++23) 현재 스레드에서, 따라서 인자들의 평가와 복사/이동 중에 발생하는 모든 예외는 새 스레드를 시작하지 않고 현재 스레드에서 발생합니다.
이러한 오버로드는 다음 조건에서만 오버로드 해결에 참여합니다: std:: remove_cvref_t < F > std::jthread 와 동일한 타입이 아닌 경우.
다음 중 하나라도 false 인 경우, 프로그램은 형식 오류를 가집니다:
생성자 호출의 완료는 synchronizes with 새로운 실행 스레드에서 f 의 복사본 호출 시작과 동기화됩니다.
4) 복사 생성자가 삭제되었습니다; 스레드는 복사할 수 없습니다. 두 개의 std::jthread 객체가 동일한 실행 스레드를 나타낼 수 없습니다.

목차

매개변수

other - std::jthread 객체를 생성하기 위한 다른 std::jthread 객체
f - Callable 새 스레드에서 실행할 호출 가능 객체
args - 새 함수에 전달할 인수들

사후 조건

1) get_id() std::jthread::id() 와 같습니다(즉, joinable() false 를 반환함). 그리고 get_stop_source ( ) . stop_possible ( ) false 입니다.
2) other. get_id ( ) std::jthread::id() 와 같고, get_id() 가 생성자 시작 전 other. get_id ( ) 의 값을 반환하는 경우
3) get_id() std::jthread::id() 와 같지 않고 (즉, joinable() true 를 반환하며), get_stop_source ( ) . stop_possible ( ) true 인 경우.

예외

3) std::system_error 스레드를 시작할 수 없는 경우. 이 예외는 std::errc::resource_unavailable_try_again 오류 조건이나 다른 구현별 오류 조건을 나타낼 수 있습니다.

참고 사항

스레드 함수에 전달되는 인수들은 값에 의해 이동되거나 복사됩니다. 참조 인수를 스레드 함수에 전달해야 하는 경우, 해당 인수를 감싸야 합니다(예: std::ref 또는 std::cref 사용).

함수에서 반환되는 모든 값은 무시됩니다. 함수가 예외를 발생시키면, std::terminate 가 호출됩니다. 반환값이나 예외를 호출 스레드로 전달하기 위해서는, std::promise 또는 std::async 를 사용할 수 있습니다.

예제

#include <chrono>
#include <iostream>
#include <thread>
#include <utility>
using namespace std::literals;
void f1(int n)
{
    for (int i = 0; i < 5; ++i)
    {
        std::cout << "Thread 1 executing\n";
        ++n;
        std::this_thread::sleep_for(10ms);
    }
}
void f2(int& n)
{
    for (int i = 0; i < 5; ++i)
    {
        std::cout << "Thread 2 executing\n";
        ++n;
        std::this_thread::sleep_for(10ms);
    }
}
class foo
{
public:
    void bar()
    {
        for (int i = 0; i < 5; ++i)
        {
            std::cout << "Thread 3 executing\n";
            ++n;
            std::this_thread::sleep_for(10ms);
        }
    }
    int n = 0;
};
class baz
{
public:
    void operator()()
    {
        for (int i = 0; i < 5; ++i)
        {
            std::cout << "Thread 4 executing\n";
            ++n;
            std::this_thread::sleep_for(10ms);
        }
    }
    int n = 0;
};
int main()
{
    int n = 0;
    foo f;
    baz b;
    std::jthread t0; // t0는 스레드가 아님
    std::jthread t1(f1, n + 1); // 값으로 전달
    std::jthread t2a(f2, std::ref(n)); // 참조로 전달
    std::jthread t2b(std::move(t2a)); // t2b가 이제 f2()를 실행 중. t2a는 더 이상 스레드가 아님
    std::jthread t3(&foo::bar, &f); // t3는 객체 f에서 foo::bar()를 실행
    std::jthread t4(b); // t4는 객체 b의 복사본에서 baz::operator()를 실행
    t1.join();
    t2b.join();
    t3.join();
    std::cout << "Final value of n is " << n << '\n';
    std::cout << "Final value of f.n (foo::n) is " << f.n << '\n';
    std::cout << "Final value of b.n (baz::n) is " << b.n << '\n';
    // t4는 소멸 시 join됨
}

가능한 출력:

Thread 2 executing
Thread 1 executing
Thread 4 executing
Thread 3 executing
Thread 3 executing
Thread 4 executing
Thread 2 executing
Thread 1 executing
Thread 3 executing
Thread 1 executing
Thread 4 executing
Thread 2 executing
Thread 3 executing
Thread 1 executing
Thread 4 executing
Thread 2 executing
Thread 3 executing
Thread 1 executing
Thread 4 executing
Thread 2 executing
Final value of n is 5
Final value of f.n (foo::n) is 5
Final value of b.n (baz::n) is 0

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
LWG 3476 C++20 오버로드 (3) 이 (decayed된 타입의)
F 와 인자 타입들이 이동 생성 가능할 것을 직접 요구함
이러한 요구사항들을
제거함 [1]
  1. 이동 생성 가능성은 이미 간접적으로 std::is_constructible_v 에 의해 요구됩니다.

참고 항목

새로운 thread 객체를 생성함
( std::thread 의 public 멤버 함수)
C 문서 for thrd_create