이 질문과 느슨하게 관련이 있습니다. std :: thread는 C ++ 11에서 풀링됩니까? . 질문은 다르지만 의도는 동일합니다.
질문 1 : 값 비싼 스레드 생성을 방지하기 위해 자체 (또는 타사 라이브러리) 스레드 풀을 사용하는 것이 여전히 타당합니까?
다른 질문의 결론은 std::thread
풀링 에 의존 할 수 없다는 것입니다 (그럴 수도 있고 아닐 수도 있음). 그러나 std::async(launch::async)
풀링 될 가능성이 훨씬 더 높은 것 같습니다.
표준에 의해 강제된다고 생각하지 않지만 IMHO는 스레드 생성이 느리면 모든 좋은 C ++ 11 구현이 스레드 풀링을 사용할 것이라고 기대합니다. 새 스레드를 만드는 것이 저렴한 플랫폼에서만 항상 새 스레드를 생성 할 것으로 예상합니다.
질문 2 : 이것이 바로 제 생각이지만 증명할 사실이 없습니다. 나는 아주 잘 착각 할 수 있습니다. 교육받은 추측입니까?
마지막으로 스레드 생성이 다음과 같이 표현 될 수 있다고 생각하는 방법을 먼저 보여주는 샘플 코드를 제공했습니다 async(launch::async)
.
예 1 :
thread t([]{ f(); });
// ...
t.join();
된다
auto future = async(launch::async, []{ f(); });
// ...
future.wait();
예제 2 : 스레드 실행 및 삭제
thread([]{ f(); }).detach();
된다
// a bit clumsy...
auto dummy = async(launch::async, []{ f(); });
// ... but I hope soon it can be simplified to
async(launch::async, []{ f(); });
질문 3 : async
버전보다 버전을 선호 thread
합니까?
나머지는 더 이상 질문의 일부가 아니라 설명을위한 것입니다.
반환 값을 더미 변수에 할당해야하는 이유는 무엇입니까?
불행히도 현재 C ++ 11 표준은 반환 값을 캡처하도록 강제합니다. std::async
그렇지 않으면 소멸자가 실행되어 작업이 종료 될 때까지 차단됩니다. 일부는 표준 오류로 간주합니다 (예 : Herb Sutter).
cppreference.com 의이 예제는이를 잘 보여줍니다.
{
std::async(std::launch::async, []{ f(); });
std::async(std::launch::async, []{ g(); }); // does not run until f() completes
}
또 다른 설명 :
스레드 풀이 다른 합법적 인 용도로 사용될 수 있다는 것을 알고 있지만이 질문에서는 값 비싼 스레드 생성 비용을 피하는 측면에만 관심이 있습니다 .
특히 리소스에 대한 더 많은 제어가 필요한 경우 스레드 풀이 매우 유용한 상황이 여전히 있다고 생각합니다. 예를 들어 서버는 빠른 응답 시간을 보장하고 메모리 사용량의 예측 가능성을 높이기 위해 고정 된 수의 요청 만 동시에 처리하기로 결정할 수 있습니다. 스레드 풀은 괜찮을 것입니다.
스레드 로컬 변수는 자신의 스레드 풀에 대한 인수가 될 수도 있지만 실제로 관련성이 있는지 확실하지 않습니다.
std::thread
초기화 된 스레드 로컬 변수없이 시작 되는 새 스레드를 만듭니다. 아마도 이것은 당신이 원하는 것이 아닙니다.- 에 의해 생성 된 스레드에서는 스레드를
async
재사용 할 수 있었기 때문에 다소 불분명합니다. 내 이해에 따르면 스레드 로컬 변수는 재설정이 보장되지 않지만 실수 할 수 있습니다. - 반면에 자체 (고정 크기) 스레드 풀을 사용하면 실제로 필요한 경우 모든 권한을 얻을 수 있습니다.
std::async()
. 스레드 풀에서 사소하지 않은 thread_local 소멸자를 지원하는 방법이 궁금합니다.
launch::async
경우에만있는 것처럼 처리 launch::deferred
하고 비동기 적으로 실행하지 않는 것으로 나타났습니다. 따라서 실제로 해당 버전의 libstdc ++는 "선택"합니다. 달리 강제하지 않는 한 항상 deferred를 사용합니다.
std::async
성능면에서 아름다운 것이 될 수 있습니다. 스레드 풀에 의해 자연스럽게 지원되는 표준 단기 실행 작업 실행 시스템 일 수 있습니다. 지금 당장 std::thread
은 스레드 함수가 값을 반환 할 수 있도록하기 위해 약간의 쓰레기가 붙어 있습니다. 아, 그리고 그들은 std::function
완전히 겹치는 중복 된 "지연된"기능을 추가했습니다 .
std::async(launch::async)
풀링 될 가능성이 훨씬 더 높은 것 같습니다." 아니요, 그게std::async(launch::async | launch::deferred)
합쳐질 수 있다고 생각합니다 . 단지와 함께launch::async
작업에 관계없이 다른 작업이 실행중인 새로운 스레드에서 출시 될 예정이다. 정책launch::async | launch::deferred
을 통해 구현은 어떤 정책을 선택할 수 있지만 더 중요한 것은 어떤 정책을 선택하는 것을 지연시키는 것입니다. 즉, 스레드 풀의 스레드가 사용 가능해질 때까지 기다린 다음 비동기 정책을 선택할 수 있습니다.