我尝试创建一个抽象类来并行化一些作品。我希望有一些东西,我可以做很多工作,而不关心它是如何完成的。但是我有一个奇怪的错误,当我运行它时,我得到了一个控制台输出"纯粹的虚拟方法叫做#34;但是当我编译它时我没有任何问题。 C ++旨在避免这种呼叫?不是吗?
这是我的抽象类:
#ifndef LIBRARIES_PARALLELISABLEPROCESS_HPP
#define LIBRARIES_PARALLELISABLEPROCESS_HPP
/* C/C++ standard libraries */
#include <string>
#include <vector>
#include <stack>
#include <thread>
#include <mutex>
#include <iostream>
/* Local inclusions */
namespace Libraries
{
template< typename type_t >
class ParallelisableProcess
{
public:
void
createTask (const type_t & data)
{
/* Adding works to the queue. */
{
std::lock_guard< std::mutex > lock(m_pendingJobsAccess);
m_pendingJobs.emplace(data);
}
/* Try to start a worker if room there.
* Current worker ID to pass to process function. */
auto workerID = 0;
for ( auto & worker : m_workers )
{
if ( worker.isActive )
{
workerID++;
continue;
}
/* Just making the process quit gently. */
if ( worker.process.joinable() )
worker.process.join();
std::cout << "Job given to worker #" << workerID << std::endl;
worker.isActive = true;
worker.process = std::thread(&ParallelisableProcess::process, this, workerID);
return;
}
std::cout << "All workers are busy ! " << m_pendingJobs.size() << " works pending." << std::endl;
}
protected:
ParallelisableProcess (size_t workersCount)
: m_workers(workersCount)
{
}
virtual
~ParallelisableProcess (void)
{
for ( auto & worker : m_workers )
{
if ( worker.process.joinable() )
worker.process.join();
}
}
/** \brief This method takes care to pull out from the queue the next job. */
bool
getNextJob (type_t & data)
{
std::lock_guard< std::mutex > lock(m_pendingJobsAccess);
if ( m_pendingJobs.size() > 0 )
{
data = m_pendingJobs.top();
m_pendingJobs.pop();
return true;
}
return false;
}
/** \brief Task keeper. */
void
process (int workerID)
{
type_t data;
while ( this->getNextJob(data) )
{
std::cout << "Launching a real task !" << std::endl;
this->task(data);
}
/* all jobs done, telling the process is inactive. */
m_workers[workerID].isActive = false;
}
/** \brief The process to build in child class. */
virtual void task (type_t & data) = 0;
private:
struct Worker
{
bool isActive = false;
std::thread process;
};
std::vector< Worker > m_workers;
std::mutex m_pendingJobsAccess;
std::stack< type_t > m_pendingJobs;
};
} /* End of namespace */
#endif /* LIBRARIES_PARALLELISABLEPROCESS_HPP */
这是我的简单测试:
#include <ParallelisableProcess.hpp>
using namespace std;
using namespace Libraries;
class DumbassWorker final : public ParallelisableProcess< int >
{
public:
DumbassWorker (void)
: ParallelisableProcess(4)
{
}
private:
virtual void
task (int & data) override final
{
std::cout << "I'm working for " << data << " secondes.\n" << std::endl;
std::this_thread::sleep_for(1s * data);
std::cout << "My job is done sir !\n" << std::endl;
}
};
int
main (int argc, const char * argv[], char * envp[])
{
DumbassWorker worker;
worker.createTask(5);
worker.createTask(7);
worker.createTask(9);
worker.createTask(10);
worker.createTask(15);
worker.createTask(2);
worker.createTask(4);
worker.createTask(10);
worker.createTask(5);
worker.createTask(7);
worker.createTask(9);
worker.createTask(10);
return 0;
}
我不明白为什么我要调用纯虚方法?也许我是盲人,但我无法弄清楚......
这是输出:
Job given to worker #0
Job given to worker #1
Job given to worker #2
Job given to worker #3
Launching a real task !
I'm working for 10 secondes.
Launching a real task !
I'm working for 9 secondes.
Launching a real task !
I'm working for 7 secondes.
All workers are busy ! 2 works pending.
All workers are busy ! 3 works pending.
All workers are busy ! 4 works pending.
All workers are busy ! 5 works pending.
All workers are busy ! 6 works pending.
All workers are busy ! 7 works pending.
All workers are busy ! 8 works pending.
All workers are busy ! 9 works pending.
Launching a real task !
pure virtual method called
terminate called without an active exception
Le programme s'est terminé subitement. (***Come from french dev environement)
The process was ended forcefully.
答案 0 :(得分:0)
也许问题是你在基类的析构函数中加入线程,此时已经调用了孩子的析构函数。 Vptr更改为当前执行的析构函数的类。
答案 1 :(得分:0)
我得到了解决方案...... DumbassWorker析构函数首先被调用,它使DumbassWorker类的task()方法无效。所以为了让事情等待所有线程的结束,我不得不做一个&#34;等待&#34; ParallelisableProcess中的方法,我在DumbassWorker的析构函数中调用它来阻止执行,然后以正确的顺序调用析构函数。它不优雅,但它有效......
现在输出是:
java -jar boot.jar --spring.config.location=classpath:/database.properties