Multithreading 我试图建立一个工人阶级,但我得到了;纯虚拟方法称为;
我尝试创建一个抽象类来并行一些工作。我想有一些我可以投入大量工作的东西,而不在乎它是如何完成的。但我有一个奇怪的bug,当我运行它时,我得到了一个控制台输出“pure virtual method called”,但我编译它时没有任何问题。C++是为了避免那种调用?没有 这是我的抽象类:Multithreading 我试图建立一个工人阶级,但我得到了;纯虚拟方法称为;,multithreading,c++11,abstract-class,Multithreading,C++11,Abstract Class,我尝试创建一个抽象类来并行一些工作。我想有一些我可以投入大量工作的东西,而不在乎它是如何完成的。但我有一个奇怪的bug,当我运行它时,我得到了一个控制台输出“pure virtual method called”,但我编译它时没有任何问题。C++是为了避免那种调用?没有 这是我的抽象类: #ifndef LIBRARIES_PARALLELISABLEPROCESS_HPP #define LIBRARIES_PARALLELISABLEPROCESS_HPP /* C/C++ standar
#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 */
可能问题是您在基类的析构函数中加入了线程,此时子类的析构函数已经被调用了。Vptr更改为当前执行的析构函数的类 我找到了解决办法。。。首先调用DumbassWorker析构函数,使DumbassWorker类中的task()方法无效。因此,为了让所有线程都等待结束,我必须在ParallelisableProcess中创建一个“wait”方法,我在DumbassWorker的析构函数中调用该方法来阻止执行,然后按正确的顺序调用析构函数。虽然不雅致,但很管用 现在输出为:
[ParallelisableProcess] Im built !
[DumbassWorker] Im built !
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 starting a job !
Launching a real task !
I'm starting a job !
Launching a real task !
I'm starting a job !
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.
[DumbassWorker] Im dying...
0 is waiting to die...
My job is done sir !.
Launching a real task !
I'm starting a job !
My job is done sir !.
Launching a real task !
I'm starting a job !
My job is done sir !.
Launching a real task !
I'm starting a job !
Launching a real task !
I'm starting a job !
My job is done sir !.
My job is done sir !.
My job is done sir !.
Launching a real task !
I'm starting a job !
Launching a real task !
I'm starting a job !
Launching a real task !
I'm starting a job !
My job is done sir !.
Launching a real task !
I'm starting a job !
My job is done sir !.
Launching a real task !
I'm starting a job !
My job is done sir !.
My job is done sir !.
Worker #My job is done sir !.
0 is killed !
1 is waiting to die...
My job is done sir !.
Worker #1 is killed !
2 is waiting to die...
Worker #2 is killed !
3 is waiting to die...
Worker #3 is killed !
I died
[ParallelisableProcess] Im dying...
我的猜测是,进程在所有线程完成之前结束,这会导致对象被破坏,当对象在线程仍在运行时被破坏,并且可能在退出之前调用
任务时,会发生奇怪的事情。您需要等待所有作业完成后才能退出进程(离开main
)。是的,但是,我要求析构函数(从Parallelisable对象)在完全销毁之前加入所有线程。您认为std::this_tread::sleep_for不适合伪造工作吗?是的,这就是问题所在
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.
[ParallelisableProcess] Im built !
[DumbassWorker] Im built !
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 starting a job !
Launching a real task !
I'm starting a job !
Launching a real task !
I'm starting a job !
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.
[DumbassWorker] Im dying...
0 is waiting to die...
My job is done sir !.
Launching a real task !
I'm starting a job !
My job is done sir !.
Launching a real task !
I'm starting a job !
My job is done sir !.
Launching a real task !
I'm starting a job !
Launching a real task !
I'm starting a job !
My job is done sir !.
My job is done sir !.
My job is done sir !.
Launching a real task !
I'm starting a job !
Launching a real task !
I'm starting a job !
Launching a real task !
I'm starting a job !
My job is done sir !.
Launching a real task !
I'm starting a job !
My job is done sir !.
Launching a real task !
I'm starting a job !
My job is done sir !.
My job is done sir !.
Worker #My job is done sir !.
0 is killed !
1 is waiting to die...
My job is done sir !.
Worker #1 is killed !
2 is waiting to die...
Worker #2 is killed !
3 is waiting to die...
Worker #3 is killed !
I died
[ParallelisableProcess] Im dying...