在C ++中扩展Job / Worker多线程系统

问题描述 投票:0回答:1

我一直在阅读Ben Hoffman(https://benhoffman.tech/cpp/general/2018/11/13/cpp-job-system.html)的教程

我已经尝试将他所拥有的Job / Worker系统的版本放在一起,但是我一直在尝试使用可变参数,而不是使用void*作为参数然后转换为已知结构。想法是,作业需要一个“父级”来执行方法,指向该方法的函数指针以及一个或多个自变量的Args...。但是,如果尝试构建,则会收到内部编译器错误。这是工作类别:

template <class T, typename... Args>
struct JobMemberFunc : IJob
{
    JobMemberFunc(T* aParent, void (T::* f)(Args...), Args... Args)
    {
        parentObj = aParent;
        func_ptr = f;
        saved_args = ::std::make_tuple (::std::move(Args)...);
    }

    virtual bool invoke() override
    {
        if (!parentObj) { return false; }

        (parentObj->*func_ptr)(::std::move(saved_args));
        return true;
    }

    /** the object to invoke the function pointer on */
    T* parentObj;

    /** The function pointer to call when we invoke this function */
    void (T::* func_ptr)(Args...);

    ::std::tuple<Args...> saved_args;
};


struct CpuJob
{
    IJob* jobPtr = nullptr;
};

然后是AddJob方法,实际发生内部编译器错误。

template <typename T, typename... Args>
void AddJob(T* aParent, void(T::* func_ptr)(Args...), Args... args)
{//This curly bracket is where the internal compiler error happens
    CpuJob aJob = {};

    JobMemberFunc<T, Args...>* jobPtr = new JobMemberFunc<T, Args...>(aParent, func_ptr, 
    std::forward<Args>(args)...);

    aJob.jobPtr = jobPtr;

    locklessReadyQueue.enqueue(aJob);
}

很高兴得知这是尝试执行此操作的错误/错误方法。我曾考虑过取消它,并拥有一个标准化的参数列表或进行多态操作,但我真的很想进行这项工作,因此我可以要求工作系统做我喜欢的任何事情。

谢谢!

c++ multithreading templates variadic
1个回答
0
投票

[std::function<void()>(与lambda结合使用)已经完成了您要使用std::function<void()>进行的操作。

JobMemberFunc

这样,您可以将任何函数调用作为作业提交。

例如,呼叫void AddJob(std::function<void()>&& job) { locklessReadyQueue.enqueue(std::move(job)); } 变为:

some_obj.some_method(some_arg)

不再有丑陋的指针指向成员的东西...

您可以在这里找到更多完整的线程池示例: AddJob([&] { some_obj.some_method(some_arg); });

© www.soinside.com 2019 - 2024. All rights reserved.