Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 我试图建立一个工人阶级,但我得到了;纯虚拟方法称为;_Multithreading_C++11_Abstract Class - Fatal编程技术网

Multithreading 我试图建立一个工人阶级,但我得到了;纯虚拟方法称为;

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

我尝试创建一个抽象类来并行一些工作。我想有一些我可以投入大量工作的东西,而不在乎它是如何完成的。但我有一个奇怪的bug,当我运行它时,我得到了一个控制台输出“pure virtual method called”,但我编译它时没有任何问题。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 */

可能问题是您在基类的析构函数中加入了线程,此时子类的析构函数已经被调用了。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...