std :: packaged_task를 수락하고 미래를 제공해야하는 스레드 풀이 있습니다.
template<typename RetType>
template<typename Args...>
std::future<RetType> submitWork(std::packaged_task<RetType(Args...)>&& callableWork>);
보시다시피 packaged_task는 템플릿입니다. 이제 내 스레드 풀은 잠금이없는 대기열을 클래스의 구성원으로 사용합니다.
class ThreadPool
{
public:
private:
llQueue<boost::variant<???>> workQueue;
}
작업 대기열이 submitWork가 호출하는 유형의 변형이되기를 원합니다. 예 :이 코드
bool runByPool(int var)
{
//do stuff
}
int runAlso(char c)
{
//do other stuff
}
ThreadPool pool; // 4 worker threads
pool.submitWork<bool(int)>(std::bind(runByPool, 1));
pool.submitWork<int<c>>(std::bind(runAlso, 'a'));
컴파일시 workQueue에 다음 유형을 제공합니다.
llQueue<boost::variant<std::packaged_task<bool(int)>,
std::packaged_task<int(c)>
>
>
클래스 멤버가 템플릿 제출 작업의 유형을 사용하도록하려면 어떻게해야합니까? 나는 llQueue가 std :: packaged_task 만 보유하도록 강제하고 싶습니다. 이는 고성능이 필요하기 때문에 힙 할당을 피할 수 있도록 변형을 사용했습니다.
힙 할당을 피하고 싶습니다. 모든 반환 유형 또는 매개 변수 유형으로 모든 작업을 실행할 수 있도록 동일한 풀이 필요합니다.
게시 한 코드는 대부분 컴파일되지 않습니다.
pool.submitWork<bool(int)>(std::bind(runByPool, 1));
의 서명 std::bind(runByPool, 1)
이 bool()
아닙니다 bool(int)
. 다른 예제에서도 동일한 오류가 발생하며 다른 구문 오류를 무시합니다.
std::future<RetType> submitWork(std::packaged_task<RetType&&(Args&&...)&& callableWork>);
이 서명은 광기입니다. 그것은해야한다;
std::future<RetType> submitWork(std::packaged_task<RetType(Args...)> callableWork);
다음으로, 균일하지 않은 유형의 인수가 여전히 필요한 작업을 수행하는 것은 거의 의미가 없습니다. 귀하의 예에 반영됩니다.
사실 여기에서 패키지 작업을 수행하는 것은 의미가 없습니다.
std::future<RetType> submitWork(std::function<RetType()> callableWork>);
더 의미가 있습니다. T를 반환하는 작업을 수행하고 미래 T를 반환합니다.
llQueue<boost::variant<???>> workQueue;
여기에는 변형이 필요하지 않습니다. 실행할 수있는 작업 대기열이 필요합니다. 반환 유형은 이미 다른 곳으로 라우팅되어야하며 해당 인수는 이미 바인딩되어 있습니다.
llQueue<std::function<void()>> workQueue;
이제 기술적 인 문제가 남아 있습니다. std::function<void()>
복사 가능해야합니다. callableWork를 미래에 연결하는 쉬운 방법은 복사 불가능한 패키지 작업을 남깁니다.
이에 대한 몇 가지 방법이 있습니다. 첫 번째는 패키지 된 작업을 공유 ptr에 넣은 다음이를 함수에 저장하는 것입니다. 두 번째는 packaged_task<T()>
서명으로 만 호출 void()
할 수 있는 이동 이며 packaged_task<void()>
.
그래서 우리는 완전한 원으로 돌아옵니다.
struct ThreadPool {
template<class F, class R=std::result_of_t<F&()>>
std::future<R> submitWork(F f){
auto task=std::packaged_task<R()>(std::move(f));
auto r=task.get_future();
workQueue.push_back(std::packaged_task<void()>(std::move(task)));
return r;
}
std::vector<std::packaged_task<void()>> workQueue;
// or:
//llQueue<std::packaged_task<void()>> workQueue;
// with changes to how things are enqueued
};
보너스로 반환 유형을 추론합니다. 라이브 예 .
나는 적어도 하나의 C ++ 컴파일러가 망가 져서 패키징 된 작업을 복사 할 수있는 내용을 요구하는 것을 보았다고 생각합니다. 따라서 공유 된 ptr 포함 함수는 백업 계획이 될 수 있습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다