如何在抽象函数类型中创建线程池任务? 我试图实现非常简单的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函数<