Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在抽象函数类型中创建线程池任务? 我试图实现非常简单的C++线程池。 到目前为止,我已经检查过了。 但是,我想以抽象的形式完成任务。 我已经搜索了几十篇文章,它们似乎不是我想要的。 (也许我的关键词不合适…) 目前,只有 void (*)()_C++_Task_Threadpool_Abstraction - Fatal编程技术网

如何在抽象函数类型中创建线程池任务? 我试图实现非常简单的C++线程池。 到目前为止,我已经检查过了。 但是,我想以抽象的形式完成任务。 我已经搜索了几十篇文章,它们似乎不是我想要的。 (也许我的关键词不合适…) 目前,只有 void (*)()

如何在抽象函数类型中创建线程池任务? 我试图实现非常简单的C++线程池。 到目前为止,我已经检查过了。 但是,我想以抽象的形式完成任务。 我已经搜索了几十篇文章,它们似乎不是我想要的。 (也许我的关键词不合适…) 目前,只有 void (*)(),c++,task,threadpool,abstraction,C++,Task,Threadpool,Abstraction,表单可以接受为任务函数。 下面是简单的代码 #include <iostream> #include <queue> #include <thread> #include <mutex> #include <Windows.h> class CYSThreadPool { private: static std::thread** s_ppThreads; static long s_lThreadCount;

表单可以接受为任务函数。 下面是简单的代码

#include <iostream>
#include <queue>
#include <thread>
#include <mutex>
#include <Windows.h>

class CYSThreadPool
{
private:

    static std::thread** s_ppThreads;
    static long s_lThreadCount;
    static bool s_bJoin;
    static std::mutex* s_pMutexJoin;

    static std::queue<void (*)()> s_queueTasks;
    static std::mutex* s_pMutexTasks;

    CYSThreadPool(){}
    ~CYSThreadPool(){}

    static void ThreadFunction()
    {
        while (true)
        {
            if (!s_pMutexJoin->try_lock())
                continue;

            bool bJoin = s_bJoin;
            s_pMutexJoin->unlock();

            if (bJoin)
                break;

            if (!s_pMutexTasks->try_lock())
                continue;

            void (*fp)() = nullptr;
            if (s_queueTasks.size() > 0ull)
            {
                fp = s_queueTasks.front();
                s_queueTasks.pop();
            }

            s_pMutexTasks->unlock();

            if (fp != nullptr)
                fp();
        }
    }

public:

    enum class EResult : unsigned long
    {
        Success = 0ul,
        Fail_Undefined = 1ul,
        Fail_InvalidThreadCount = 2ul,
        Fail_ArgumentNull = 3ul
    };

    static const EResult Join()
    {
        if (s_ppThreads == nullptr)
        {
            if (s_lThreadCount == 0l)
                return EResult::Success;
            else
                return EResult::Fail_Undefined;
        }
        else
        {
            if (s_lThreadCount <= 0l)
                return EResult::Fail_Undefined;
            else
            {
                s_pMutexJoin->lock();
                s_bJoin = true;
                s_pMutexJoin->unlock();

                for (long i = 0l; i < s_lThreadCount; ++i)
                {
                    s_ppThreads[i]->join();
                    s_ppThreads[i] = nullptr;
                }

                delete s_ppThreads;
                s_ppThreads = nullptr;
                s_lThreadCount = 0l;

                s_pMutexJoin->lock();
                s_bJoin = false;
                s_pMutexJoin->unlock();
            }
        }

        return EResult::Success;
    }

    static const EResult CreateThreads(const long _lThreadCount)
    {
        if (_lThreadCount < 0l)
            return EResult::Fail_InvalidThreadCount;

        if (Join() != EResult::Success)
            return EResult::Fail_Undefined;

        if (_lThreadCount == 0l)
            return EResult::Success;

        s_ppThreads = new std::thread*[_lThreadCount]{};

        for (long i = 0l; i < _lThreadCount; ++i)
            s_ppThreads[i] = new std::thread(ThreadFunction);

        s_lThreadCount = _lThreadCount;

        return EResult::Success;
    }

    static const EResult AddTask(void (*_fp)())
    {
        if (_fp == nullptr)
            return EResult::Fail_ArgumentNull;

        s_pMutexTasks->lock();
        s_queueTasks.push(_fp);
        s_pMutexTasks->unlock();

        return EResult::Success;
    }
};

std::thread** CYSThreadPool::s_ppThreads = nullptr;
long CYSThreadPool::s_lThreadCount = 0l;
bool CYSThreadPool::s_bJoin = false;
std::mutex* CYSThreadPool::s_pMutexJoin = new std::mutex();
std::queue<void (*)()> CYSThreadPool::s_queueTasks;
std::mutex* CYSThreadPool::s_pMutexTasks = new std::mutex();

void Test0()
{
    for (long i = 0l; i < 100000l; ++i)
    {
        std::cout << "A";
    }
}

int main()
{
    CYSThreadPool::EResult eResult = CYSThreadPool::Join();
    eResult = CYSThreadPool::CreateThreads(-1l);
    eResult = CYSThreadPool::CreateThreads(1l);
    eResult = CYSThreadPool::CreateThreads(0l);
    eResult = CYSThreadPool::CreateThreads(2l);

    CYSThreadPool::AddTask(Test0);

    Sleep(1000ul);

    CYSThreadPool::Join();

    return 0;
}
#包括
#包括
#包括
#包括
#包括
类线程池
{
私人:
静态标准::线程**s\ppThreads;
静态长s_lThreadCount;
静态布尔s_bJoin;
静态std::mutex*s_pMutexJoin;
静态std::队列s_queueTasks;
静态std::mutex*s_pmutextask;
CYSThreadPool(){}
~CYSThreadPool(){}
静态函数()
{
while(true)
{
如果(!s_pMutexJoin->try_lock())
继续;
bool bJoin=s_bJoin;
s_pMutexJoin->unlock();
如果(bJoin)
打破
如果(!s_pMutexTasks->try_lock())
继续;
void(*fp)(=nullptr;
如果(s_queueTasks.size()>0ull)
{
fp=s_queueTasks.front();
s_queueTasks.pop();
}
s_pMutexTasks->unlock();
如果(fp!=nullptr)
fp();
}
}
公众:
枚举类EResult:无符号长
{
成功=0ul,
失败\未定义=1ul,
失败\无效线程数=2ul,
失败\u ArgumentNull=3ul
};
静态constresult Join()
{
如果(s_ppThreads==nullptr)
{
如果(s_lThreadCount==0l)
返回EResult::Success;
其他的
返回EResult::Fail\u未定义;
}
其他的
{
如果(s_lThreadCount lock();
s_bJoin=真;
s_pMutexJoin->unlock();
用于(长i=0l;ijoin();
s_ppThreads[i]=nullptr;
}
删除Sppu线程;
s_ppThreads=nullptr;
s_lThreadCount=0升;
s_pMutexJoin->lock();
s_bJoin=假;
s_pMutexJoin->unlock();
}
}
返回EResult::Success;
}
静态常量结果CreateThreads(常量long\u lThreadCount)
{
如果(_lThreadCount<0升)
返回EResult::Fail\u InvalidThreadCount;
if(Join()!=EResult::Success)
返回EResult::Fail\u未定义;
如果(_lThreadCount==0l)
返回EResult::Success;
s_ppThreads=newstd::thread*[[u lThreadCount]{};
用于(长i=0l;i<\u lThreadCount;++i)
s_ppThreads[i]=新的std::thread(ThreadFunction);
s_lThreadCount=_lThreadCount;
返回EResult::Success;
}
静态constresult AddTask(void(*\u fp)()
{
如果(_fp==nullptr)
返回EResult::Fail\u ArgumentNull;
s_pMutexTasks->lock();
s_queueTasks.push(_fp);
s_pMutexTasks->unlock();
返回EResult::Success;
}
};
std::thread**CYSThreadPool::s_ppThreads=nullptr;
长线程池::s_lThreadCount=0l;
bool CYSThreadPool::s_bJoin=false;
std::mutex*CYSThreadPool::s_pMutexJoin=new std::mutex();
std::queue CYSThreadPool::s_queueTasks;
std::mutex*CYSThreadPool::s_pMutexTasks=new std::mutex();
void Test0()
{
用于(长i=0l;i<100000l;+i)
{

std::cout所以这里有几件事可以改进您的代码:

  • 您可以使用而不是
    void(*)(
    。这将允许您调用任何可调用的函数指针,而不仅仅是函数指针,方法是将它们包装在lambda中,例如
    CYSThreadPool::AddTask([](){Add(3,1);});
  • 更好的方法是,使用virtual
    .Run()
    方法创建一个抽象基类,比如说
    Task
    ,然后使用它。您可以派生
    FunctionPointerTask
    StdFunctionTask
    (您可以明显更改名称)您可以创建,比如说
    ProcessResource1Task
    ,并将必要的参数传递给构造函数,以便
    .Run()
    只执行它
  • 你的
    ThreadFunction
    工作效率非常低。你一直在
    try\u lock
    上旋转。不要。改用
  • 更好的是,将排队的内容移动到一个单独的线程安全队列类中
  • 你的代码不是异常安全的。不要使用手动锁定/尝试锁定,而是使用或。因为你的代码很容易死锁。如果你必须使用手动锁定/尝试锁定,那么你必须使用try-catch
  • 大量静态变量。不要。将所有变量都设为非静态成员,添加适当的构造函数和析构函数。一旦加入线程池,线程池将完全不可用。Plus Join()不是线程安全的(如果线程池不是完全静态的,则关系不大)
  • 您可以通过使
    bool s_bJoin
    来提高性能。无需在锁下读/写它
  • 可能还有其他一些问题,这就是我现在看到的


    您还可以查看一个不错的线程池实现。它很短,并利用了上面的大部分提示。

    因此,这里有几点可以改进您的代码:

  • 您可以使用而不是
    void(*)(
    。这将允许您调用任何可调用的函数指针,而不仅仅是函数指针,方法是将它们包装在lambda中,例如
    CYSThreadPool::AddTask([](){Add(3,1);});
  • 更好的方法是,使用virtual
    .Run()
    方法创建一个抽象基类,比如说
    Task
    ,然后使用它。您可以派生
    FunctionPointerTask
    StdFunctionTask
    (您可以明显更改名称)您可以创建,比如说
    ProcessResource1Task
    ,并将必要的参数传递给构造函数,以便
    .Run()
    只执行它
  • 您的
    thread函数<