我使用C ++ 11创建了一个如下的线程池类。
#include <iostream>
#include <functional>
#include <vector>
#include <condition_variable>
#include <thread>
#include <mutex>
#include <queue>
#include <atomic>
#include <future>
class threadpool {
struct task {
std::size_t m_priority;
std::function<void()> m_fn;
bool operator()(task* t1, task* t2) const {
return t1->m_priority < t2->m_priority;
}
};
public:
threadpool(std::size_t nthreads);
~threadpool();
// void assign(std::function<void()> fn, std::size_t priority);
template <typename T> std::future<T> assign(std::function<T()> fn, std::size_t priority);
private:
void funnel();
std::vector<std::thread*> m_threadlist;
std::priority_queue<task*, std::vector<task*>, task> m_tasks;
std::mutex m_tasks_mtx;
std::condition_variable m_newc;
std::mutex m_newc_mtx;
std::atomic<bool> m_destruct;
};
threadpool::threadpool(std::size_t nthreads) {
for (std::size_t _n = nthreads; _n > 0; --_n)
m_threadlist.push_back(new std::thread(std::bind(&threadpool::funnel, this)));
}
threadpool::~threadpool() {
m_destruct = true;
while (!m_threadlist.empty()) {
m_newc.notify_one();
}
}
/* ... */
template <typename T>
std::future<T> assign(std::function<T()> fn, std::size_t priority) {
std::promise<T> _prom;
std::future<T> _ft = _prom.get_future();
threadpool::task* _t = new task();
_t->m_fn = std::bind([](std::promise<T>& p) {
p.set_value(fn());
}, std::ref(_prom));
_t->m_priority = priority;
{
std::lock_guard<std::mutex> _lock(m_tasks_mtx);
m_tasks.push(_t);
}
m_newc.notify_one();
return _ft;
}
void threadpool::funnel() {
while (!m_destruct) {
{
std::unique_lock<std::mutex> _lock(this->m_newc_mtx);
m_newc.wait(_lock);
}
for (;;) {
threadpool::task* _t;
{
std::lock_guard<std::mutex> _lock(m_tasks_mtx);
if (m_tasks.empty()) break;
_t = m_tasks.top();
m_tasks.pop();
}
_t->m_fn();
delete _t;
}
}
}
int count() {
return 3;
}
int main(int argc, char* argv[])
{
threadpool* herppool = new threadpool(10);
for(int i = 0; i<900;i++) {
auto derp = herppool->assign<int>(count,3); // <-- error here
//printf("%d", derp.get());
}
delete herppool;
//getchar();
}
我无法解决为什么我在指定行的MSVC 2012下出现以下错误。
1> main.cpp
1>main.obj : error LNK2001: unresolved external symbol "public: class std::future<int> __thiscall threadpool::assign<int>(class std::function<int __cdecl(void)>,unsigned int)" (??$assign@H@threadpool@@QAE?AV?$future@H@std@@V?$function@$$A6AHXZ@2@I@Z)
1>C:\Users\...\visual studio 2012\Projects\threadpool\Release\threadpool.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
对我而言,看起来该功能存在。我不知道链接器在抱怨什么,并且非常感谢帮助跟踪错误。我现在已经盯着它看了几个小时。
答案 0 :(得分:6)
如果仔细观察一下:
template <typename T>
std::future<T> assign(std::function<T()> fn, std::size_t priority)
您没有定义threadpool::assign
,而是定义名为assign
的免费函数。链接器很清楚地告诉你,你忘了定义threadpool::assign
。你需要这个:
template <typename T>
std::future<T> threadpool::assign(std::function<T()> fn, std::size_t priority)