I have two class that follow this manner to encapsulate threads inside a C++ object.
class MyThreadClass
{
public:
MyThreadClass() {/* empty */}
virtual ~MyThreadClass() {/* empty */}
/** Returns true if the thread was successfully started, false if there was an error starting the thread */
bool StartInternalThread()
{
return (pthread_create(&_thread, NULL, InternalThreadEntryFunc, this) == 0);
}
/** Will not return until the internal thread has exited. */
void WaitForInternalThreadToExit()
{
(void) pthread_join(_thread, NULL);
}
protected:
/** Implement this method in your subclass with the code you want your thread to run. */
virtual void InternalThreadEntry() = 0;
private:
static void * InternalThreadEntryFunc(void * This) {((MyThreadClass *)This)->InternalThreadEntry(); return NULL;}
pthread_t _thread;
};
Now these i need the instances of these two class to do something together, generally, a instance of class B polling a flag and do its own job until the flag is set by class A:
class A : public MyThreadClass{
protected:
virtual void InternalThreadEntry(){
doSomething();
flag.store(true);
doOtherThing();
}
private:
std::atomic_bool& flag;
};
class B : public MyThreadClass{
protected:
virtual void InternalThreadEntry(){
do{
doOwnJob();
// thus cannot use condition variable
}while(flag.load() == false);
doOther();
}
private:
std::atomic_bool& flag;
};
Since the lifecycle of this two classes instances are bounded, i create a manager class to handle some shared variables instead of using global variable.
class Manager{
private:
A a;
B b;
std::atomic_bool flag; // to shared between
};
Of course, these codes cannot be compiled, since the reference field must be be included in constructor's initialized list.
One of the ways to work around is to change class A/B's constructor signature to accept a reference to flag
, since the flag
lifecycle is bounded to these two class instances. However, this is not a valid choice since i am working on an existed code base, such change might involve massive code modification.
So it seems that i can only use a "setter" two set this flag
field within each instance. And that makes the reference member declaration impossible. Intuitively, i think about using shared_ptr/raw_ptr to shared one flag
between two class instances. But i wonder if this is "safe" manner or not? Or what is the better solution to deal with such situation?
Aucun commentaire:
Enregistrer un commentaire