2012-12-24 36 views
0

我使用C++ 11如下所示创建了一个线程池类。模板std :: future的问题返回

#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)" ([email protected]@[email protected]@[email protected]@[email protected]@[email protected][email protected]@[email protected]) 
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 ========== 

对我来说,它看起来像函数存在。我不知道链接器在抱怨什么,并且非常感谢帮助追踪错误。我一直盯着它几个小时。

回答

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) 
+0

令人难以置信!我怎么会错过这个。在11分钟内接受答案。 – kvanberendonck

+2

@kvanberendonck:当你再次得到链接器错误时,你现在可以确切地知道在哪里看到了......这就是我们学习的方式;) –