我想用C++实现一个线程池,有2个文件:一个是thread.cpp,还有一个是threadpool_test.cpp。thread.cpp有2个类,一个是threadpool,还有一个是Task。threadpool_test.cpp是调用文件。他们编译的时候报错,目前还是没有解决。下面是代码。
声明和实现
//threadp.cpp
#include<stdio.h>
#include<iostream>
#include<sys/types.h>
#include<vector>
#include<thread>
#include<pthread.h>
#include<stdlib.h>
#include<mutex>
#include<string.h>
#include<condition_variable>
using namespace std;
class Task
{
protected:
char * TaskName;
void * TaskData;
public:
Task();
Task( char * TName );
virtual int Run() = 0;
void SetData( void * TData );
void showdata();
virtual ~Task() {};
};
template<class TASK>
class ThreadPool
{
private:
int thread_num;
vector<TASK *> TaskList;
vector<thread> threads;
bool shutdown;
mutex _x;
condition_variable _cond;
public:
ThreadPool( int ThN = 10 );
int GetTaskNum();
int PushTask( TASK * task );
int StopAll();
int Create();
void * ThreadFun();
};
template<class TASK>
int ThreadPool<TASK>::Create()
{
for( int i = 0; i < thread_num; i++ )
threads.push_back( thread( &ThreadPool<TASK>::ThreadFun ) );//line54
return 0;
}
template<class TASK>
ThreadPool<TASK>::ThreadPool( int ThN ):thread_num(ThN)
{
shutdown = false;
cout << thread_num << " numbers threads will be create." << endl;
Create(); //line 63
}
template<class TASK>
int ThreadPool<TASK>::GetTaskNum()
{
return TaskList.size();
}
template<class TASK>
int ThreadPool<TASK>::PushTask( TASK * task )
{
unique_lock<mutex> locker( _x );
TaskList.push_back( task );
_x.unlock();
_cond.notify_one();
return 0;
}
template<class TASK>
void * ThreadPool<TASK>::ThreadFun()
{
thread::id tid = std::this_thread::get_id();
while(1) {
unique_lock<mutex> locker( _x );
while( TaskList.size() == 0 && !shutdown )
_cond.wait( locker );
if( shutdown ) {
locker.unlock( );
printf("Thread %lu will exit.\n",tid);
return (void *)0;
}
typename vector<TASK>::iterator iter = TaskList.begin();
if( iter != TaskList .end() ) {
TASK task = *iter;
TaskList.erase( iter );
locker.unlock( );
task.Run();
printf("%lu idle.\n",tid);
}
}
return (void *)0;
}
template<class TASK>
int ThreadPool<TASK>::StopAll()
{
if( shutdown ) return -1;
cout << "All thread will stop." << endl;
shutdown = true;
_cond.notify_all();
for( int i = 0; i < thread_num; i++ )
threads[i].join();
threads.clear();
cout << "The Threadpool is stop." << endl;
return 0;
}
Task::Task() { TaskName = NULL; TaskData = NULL; }
Task::Task( char * TName )
{
TaskName = TName;
TaskData = NULL;
}
void Task::SetData( void * TData )
{
TaskData = TData;
}
void Task::showdata()
{
cout << TaskData << endl;
}
main file
//threadpool_test.cpp
#include<iostream>
#include<vector>
#include<stdio.h>
#include<string>
#include<thread>
#include<unistd.h>
//#include "threadpool.h"
#include "threadp.cpp"
//#include "threadpool.cpp"
using namespace std;
class TaskWork : public Task
{
public:
//Task() {}
virtual int Run()
{
printf("%s\n",(char *)this->TaskData);
sleep(5);
return 0;
}
};
int main()
{
TaskWork task;
char obj[] = "abc";
task.SetData( obj );
task.showdata();
ThreadPool<TaskWork> thread_pool(10);
for( int i = 0; i < 20; i++ ) //line 33
thread_pool.PushTask( &task );
while( 1 ) {
if( thread_pool.GetTaskNum() == 0 && thread_pool.StopAll() == -1 ) {
cout << "exit the main.\n";
exit(0);
}
}
sleep(2);
return 0;
}
编译错误信息(g++4.8 & centOS 7):
[root@localhost 15.05]# g++ -g -lpthread -D_REENTRANT threadpool_test.cpp -o test -std=c++11 -fPIC
In file included from /usr/include/c++/4.8.2/thread:39:0,
from threadpool_test.cpp:6:
/usr/include/c++/4.8.2/functional: In instantiation of ‘struct std::_Bind_simple<std::_Mem_fn<void* (ThreadPool<TaskWork>::*)()>()>’:
/usr/include/c++/4.8.2/thread:137:47: required from ‘std::thread::thread (_Callable&&, _Args&& ...) [with _Callable = void* (ThreadPool<TaskWork>::*)(); _Args = {}]’
threadp.cpp:54:61: required from ‘int ThreadPool<TASK>::Create() [with TASK = TaskWork]’
threadp.cpp:63:9: required from ‘ThreadPool<TASK>::ThreadPool(int) [with TASK = TaskWork]’
threadpool_test.cpp:33:37: required from here
/usr/include/c++/4.8.2/functional:1697:61: error: no type named ‘type’ in ‘class std::result_of<std::_Mem_fn<void* (ThreadPool<TaskWork>::*)()>()>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
/usr/include/c++/4.8.2/functional:1727:9: error: no type named ‘type’ in ‘class std::result_of<std::_Mem_fn<void* (ThreadPool<TaskWork>::*)()>()>’
_M_invoke(_Index_tuple<_Indices...>)
^