Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
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!
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.
Related
Been trying to figure out how to properly handle custom events in conjunction with std::thread, haven't been able to find any code without wxThread. As i understand i need to use wxQueueEvent, but my problem is how to get the wxEvtHandler pointer to the class holding the thread. The bellow code passes a pointer of the class where i have the "onErrorEvent" function, this compiles and works, but I'm not sure if that's a "legal" way of doing it. It feels like a bad idea to use the pointer that way idk. All i want to know is if it will work hehe, doesn't need to be perfect textbook worthy code.
#include "cMain.h"
#include <iostream>
#include <thread>
using namespace std;
const int myEvtId=10000;
const int writeEvtId=10001;
wxDEFINE_EVENT(MY_EVT,wxCommandEvent);
wxDEFINE_EVENT(WRITE_EVT,wxCommandEvent);
wxBEGIN_EVENT_TABLE(cMain,wxFrame)
EVT_COMMAND(myEvtId,MY_EVT,cMain::onErrorEvent)
EVT_COMMAND(writeEvtId,WRITE_EVT,cMain::onWriteEvent)
wxEND_EVENT_TABLE()
class threadClass
{
public:
void startThread(wxEvtHandler *evtHandle)
{
threadState=true;
thr=thread(&threadClass::threadFn,this,evtHandle);
}
void endThread()
{
if(threadState)
{
threadState=false;
thr.join();
}
}
private:
bool threadFn(wxEvtHandler *evtHandle)
{
while(threadState)
{
if(error)
{
//Error occurred
wxCommandEvent *evt=new wxCommandEvent(MY_EVT,myEvtId);
wxQueueEvent(evtHandle,evt);
return false;
}
else
{
//Otherwise write data
wxCommandEvent *evt=new wxCommandEvent(WRITE_EVT,writeEvtId);
evt->SetString("Data to be written");
wxQueueEvent(evtHandle,evt);
}
this_thread::sleep_for(chrono::milliseconds(500));
}
return true;
}
private:
thread thr;
bool threadState=false;
bool error=false;
};
threadClass thrClass;
cMain::cMain() : wxFrame(nullptr,wxID_ANY,"wxWidgets template",wxPoint(30,30),wxSize(420,520))
{
txt1=new wxTextCtrl(this,wxID_ANY,"",wxPoint(20,20),wxSize(300,400),wxTE_READONLY | wxTE_MULTILINE);
wxButton *btn1=new wxButton(this,wxID_ANY,"Button 1",wxPoint(160,430),wxSize(80,40));
thrClass.startThread(this);
}
cMain::~cMain()
{
thrClass.endThread();
}
void cMain::onErrorEvent(wxCommandEvent &evt)
{
//Handle Error
thrClass.endThread();
}
void cMain::onWriteEvent(wxCommandEvent &evt)
{
//Write data
txt1->AppendText(evt.GetString()+'\n');
}
I'm using std:thread so it's compatible with existing code I've already written, so I'd rather not rewrite it with wxThread instead.
//Benji
**Edit - I revised the code to include my method of printing to the textCtrl ui element.
There is a class "Mario". This one has an virtual method: void mission(). I want override this method and run it from base class code in parallel.
But output of the following code is:
Mario works hard
LOL
Code:
#include <iostream>
#include <thread>
class Mario
{
std::thread workingField;
bool hasStarted = false;
public:
virtual void mission()
{
std::cout << "LOL" << std::endl;
}
void startMission()
{
if (!hasStarted)
{
workingField = std::thread([this]() {
this->mission();
});
hasStarted = true;
}
}
virtual ~Mario()
{
if (hasStarted)
{
workingField.join();
}
}
};
class MarioWorker : public Mario
{
public:
void mission() override final
{
std::cout << "Mario works hard" << std::endl;
}
};
int main(int argc, char *argv[])
{
MarioWorker mw;
mw.mission();
mw.startMission();
}
How can I get a double line "Mario works hard", when one of them is executed in another thread?
In other words how a base class can execute an overridden method in parallel?
I'm using GCC 9.3
The problem is, the main thread is too fast. Your main method ends, the deconstruction of mw starts, MarioWorker gets destructed and once it starts destructing the Mario it joins the thread. The thread never sees the MarioWorker as it was already destructed, all it sees is the Mario.
I want to create a thread that can be interrupted while waiting (it waits data from other processes and I want to stop the process in nice way).
I've read the 9.2 part of C++ Concurrency in Action 2nd Edition, and I've tried to implement that ideas, but I've some problem and I don't know where to check.
This is my code based on that example:
#include <iostream>
#include <stdexcept>
#include <thread>
#include <mutex>
#include <atomic>
#include <condition_variable>
#include <future>
// Exception that should be raised when there's an interruption.
// It's raised when the thread is interrupted, so we can catch
// it and finish the thread execution.
class InterruptedException : public std::runtime_error {
public:
InterruptedException(const std::string& message) : std::runtime_error(message) {}
virtual ~InterruptedException() {}
};
// Interrupt flag. This class represents a local-thread flag that
// tells if the thread is interrupted or not.
class InterruptFlag {
public:
InterruptFlag() :
m_threadConditionVariable(nullptr),
m_threadConditionVariableAny(nullptr) {}
void set() {
m_flag.store(true, std::memory_order_relaxed);
std::lock_guard<std::mutex> lk(m_setClearMutex);
if (m_threadConditionVariable) {
m_threadConditionVariable->notify_all();
}
else if (m_threadConditionVariableAny) {
m_threadConditionVariableAny->notify_all();
}
}
template <typename Lockable>
void wait(std::condition_variable_any& cv, Lockable& lk) {
struct CustomLock {
InterruptFlag* m_self;
Lockable& m_lk;
CustomLock(InterruptFlag* self, std::condition_variable_any& cond, Lockable& lk) :
m_self(self),
m_lk(lk) {
m_self->m_setClearMutex.unlock();
m_self->m_threadConditionVariableAny = &cond;
}
void unlock() {
m_lk.unlock();
m_self->m_setClearMutex.unlock();
}
void lock() {
std::lock(m_self->m_setClearMutex, lk);
}
~CustomLock() {
m_self->m_threadConditionAny = nullptr;
m_self->m_setClearMutex.unlock();
}
};
CustomLock cl(this, cv, lk);
InterruptPoint();
cv.wait(cl);
InterruptPoint();
}
void setConditionVariable(std::condition_variable& cv) {
std::lock_guard<std::mutex> lk(m_setClearMutex);
m_threadConditionVariable = &cv;
}
void clearConditionVariable() {
std::lock_guard<std::mutex> lk(m_setClearMutex);
m_threadConditionVariable = nullptr;
}
bool isSet() const {
return m_flag.load(std::memory_order_relaxed);
}
private:
std::atomic<bool> m_flag;
std::condition_variable* m_threadConditionVariable;
std::condition_variable_any* m_threadConditionVariableAny;
std::mutex m_setClearMutex;
};
// Thread-local interrupt flag instance. The variable should be
// created for every thread, since it's thread_local.
thread_local InterruptFlag ThisThreadInterruptFlag;
// Convenience class for cleaning the flag due to RAII.
struct ClearConditionVariableOnDestruct {
~ClearConditionVariableOnDestruct() {
ThisThreadInterruptFlag.clearConditionVariable();
}
};
// Function that throws the exception that tells that the thread
// is interrupted. For doing it checks the state of ThisThreadInterruptFlag.
void InterruptionPoint() {
if (ThisThreadInterruptFlag.isSet()) {
throw InterruptedException("Interrupted");
}
}
// Function that must be used inside the thread function body for waiting.
// It waits for the condition variable, when it notifies from other threads,
// but it also notifies if the thread is interrupted.
void InterruptibleWait(std::condition_variable& cv, std::unique_lock<std::mutex>& lk) {
InterruptionPoint();
ThisThreadInterruptFlag.setConditionVariable(cv);
ClearConditionVariableOnDestruct guard;
InterruptionPoint();
cv.wait_for(lk, std::chrono::milliseconds(1));
InterruptionPoint();
}
// This class represents the interruptible thread. It adds a interrupt()
// method that when called interupts the thread execution, if it's waiting
// at some point where InterruptibleWait function is locked.
class Interruptible {
public:
template <typename FunctionType>
Interruptible(FunctionType f) {
std::promise<InterruptFlag*> p;
m_internalThread = std::thread([f, &p]() {
p.set_value(&ThisThreadInterruptFlag);
try {
f();
}
catch (InterruptedException) {
}
});
m_flag = p.get_future().get();
}
void join() {
m_internalThread.join();
}
void detach() {
m_internalThread.detach();
}
bool joinable() const {
return m_internalThread.joinable();
}
void interrupt() {
if (m_flag) {
m_flag->set();
}
}
private:
std::thread m_internalThread;
InterruptFlag* m_flag;
};
std::mutex mtx;
std::unique_lock<std::mutex> lk(mtx);
int main(int argc, char* argv[]) {
std::cout << "Interrupting thread example" << std::endl;
bool test = false;
std::condition_variable cv;
auto f = [&cv, &test]() {
test = true;
InterruptibleWait(cv, lk);
// Since it locks forever, it should never reach this point.
test = false;
};
Interruptible interruptibleThread(f);
std::this_thread::sleep_for(std::chrono::milliseconds(30));
// We interrupt the function while it's blocked in InterruptibleWait
interruptibleThread.interrupt();
interruptibleThread.join();
std::cout << "test value is " << std::boolalpha << test << ". It should be true." << std::endl;
return 0;
}
Basically I create a Interruptible class representing a thread that can be interrupted. I interrupt it during its execution by calling its interrupt() method. The thread can be interrupted if it's locked with in a InterruptibleWait function call. This function behave like a std::condition.wait(), in fact it wants a reference to it, but it also handle the interruption flag.
If I start the program. I obtain an error from Visual Studio when running.
I don't know what I'm doing wrong. What should I do in order to make InterruptibleWait work correctly?
My best guess based on the given information:
The exception isn't caught in the thread entry point function, and escapes that function. When this happens in a thread started by std::thread, abort is called for you (indirectly through std::terminate) by the std::thread implementation, as required by the standard. To fix this, try catching all exceptions in the function passed to std::thread.
See the cppreference articles on std::thread and std::terminate
I have a program which I am attempting to run a process in a separate thread. Normally I would use Qt for this, but in this particular instance I can't (due to it going on to an embedded device). My concern is whether or not my current implementation will run the thread correctly, or if it will destroy the thread before processing. Below is my code:
int main(){
//code
Processor *x = new Processor;
//other code
x->startThread(s);
//more code which needs to be running seperately
}
Processor.h
Class Processor {
public:
Processor();
void startThread(std::string s);
void myCode(std::string s);
//more stuff
}
Processor.cpp
void Processor::startThread(std::string s){
std::thread(&Processor::startRecording, s).detach();
}
void Processor::myCode(std::string s){
//lots of code
}
Alternatively, if there is an easier way to start myCode from the main function rather than needing to have the class startThread, please let me know.
I suggest that you make the thread as a Processor attribute.
Run It Online
#include <iostream>
#include <memory>
#include <string>
#include <thread>
//Processor.h
class Processor {
private:
std::shared_ptr<std::thread> _th;
public:
Processor();
void startThread(std::string s);
void joinThread();
void myCode(std::string s);
void startRecording(std::string s);
//more stuff
};
//Processor.cpp
Processor::Processor() {
}
void Processor::startThread(std::string s) {
_th = std::make_shared<std::thread>(&Processor::startRecording, this, s); // "this" is the first argument ;)
}
void Processor::joinThread() {
_th->join();
}
void Processor::myCode(std::string s) {
//lots of code
}
void Processor::startRecording(std::string s) {
std::cout << "msg: " << s << std::endl;
}
// main.cpp
int main(){
//code
auto x = std::make_unique<Processor>();
//other code
x->startThread("hello");
//more code which needs to be running seperately
x->joinThread();
}
I am very new to C++.
I have a class, and I want to create a thread inside a class's function. And that thread(function) will call and access the class function and variable as well.
At the beginning I tried to use Pthread, but only work outside a class, if I want to access the class function/variable I got an out of scope error.
I take a look at Boost/thread but it is not desirable because of I don't want to add any other library to my files(for other reason).
I did some research and cannot find any useful answers.
Please give some examples to guide me. Thank you so much!
Attempt using pthread(but I dont know how to deal with the situation I stated above):
#include <pthread.h>
void* print(void* data)
{
std::cout << *((std::string*)data) << "\n";
return NULL; // We could return data here if we wanted to
}
int main()
{
std::string message = "Hello, pthreads!";
pthread_t threadHandle;
pthread_create(&threadHandle, NULL, &print, &message);
// Wait for the thread to finish, then exit
pthread_join(threadHandle, NULL);
return 0;
}
You can pass a static member function to a pthread, and an instance of an object as its argument. The idiom goes something like this:
class Parallel
{
private:
pthread_t thread;
static void * staticEntryPoint(void * c);
void entryPoint();
public:
void start();
};
void Parallel::start()
{
pthread_create(&thread, NULL, Parallel::staticEntryPoint, this);
}
void * Parallel::staticEntryPoint(void * c)
{
((Parallel *) c)->entryPoint();
return NULL;
}
void Parallel::entryPoint()
{
// thread body
}
This is a pthread example. You can probably adapt it to use a std::thread without much difficulty.
#include <thread>
#include <string>
#include <iostream>
class Class
{
public:
Class(const std::string& s) : m_data(s) { }
~Class() { m_thread.join(); }
void runThread() { m_thread = std::thread(&Class::print, this); }
private:
std::string m_data;
std::thread m_thread;
void print() const { std::cout << m_data << '\n'; }
};
int main()
{
Class c("Hello, world!");
c.runThread();
}