ScutterKey ScutterKey - 2 months ago 8
C++ Question

c++ virtual function and thread

here is my main.cpp code:

#include <opencv2/opencv.hpp>
using std::string;

#include "caffe_thread_learn.hpp"

class VideoCaptureTest : public InternalThread {
public:
string video;
explicit VideoCaptureTest(string v) : video(v) { StartInternalThread(); }
protected:
virtual void InternalThreadEntry();
};

void VideoCaptureTest::InternalThreadEntry(){
std::cout << "video child" << std::endl;
}

int main(){

InternalThread* vt = new VideoCaptureTest("/Users/zj-db0655/Documents/data/528100078_5768b1b1764438418.mp4");
delete vt;

return 0;
}


caffe_thread.cpp code:

#include "caffe_thread_learn.hpp"


InternalThread::~InternalThread() {
StopInternalThread();
}

bool InternalThread::is_started() const {
return thread_ && thread_->joinable();
}

bool InternalThread::must_stop() {
return thread_ && thread_->interruption_requested();
}

void InternalThread::StopInternalThread() {
if (is_started()) {
thread_->interrupt();
try {
thread_->join();
} catch (boost::thread_interrupted&) {
} catch (std::exception& e) {
std::cout << "Thread exception: " << e.what();
}
}
}


void InternalThread::StartInternalThread() {
thread_.reset(new boost::thread(&InternalThread::entry, this));
}

void InternalThread::entry() {
InternalThreadEntry();
}


caffe_thread.hpp code

#ifndef caffe_thread_learn_hpp
#define caffe_thread_learn_hpp

#include <stdio.h>

#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>

namespace boost { class thread; }

class InternalThread {
public:
InternalThread() : thread_() {}
virtual ~InternalThread();

/**
* Caffe's thread local state will be initialized using the current
* thread values, e.g. device id, solver index etc. The random seed
* is initialized using caffe_rng_rand.
*/
void StartInternalThread();

/** Will not return until the internal thread has exited. */
void StopInternalThread();

bool is_started() const;

protected:
/* Implement this method in your subclass
with the code you want your thread to run. */
virtual void InternalThreadEntry() { std::cout << "parent" << std::endl; }
virtual void fun() {}

/* Should be tested when running loops to exit when requested. */
bool must_stop();

private:
void entry();

boost::shared_ptr<boost::thread> thread_;
};

#endif /* caffe_thread_learn_hpp */


actually, the output is:parant

However, i think output should be:video child. Because when StartInternalThread in VideoCaptureTest is called, it will new a thread with parameter (&InternalThread::entry, this), and I think this pointer to VideoCaptureTest and will call VideoCaptureTest's InternalThreadEntry which output video child. However, it output parent.

Thanks!

Answer

This is likely a timing issue between your threads. You create a new VideoCaptureTest object then immediately delete it before the thread created in StartInternalThread has a chance to run. When the destructor is called, the object will be torn down to an InternalThread object before the output has been generated.

Either put a sleep between your new/delete in main or wait for the thread to finish before destroying it.

Comments