pthread with mutex and condition variables (C++) OOP - c++

Hello =D I am kinda stuck with a problem, I am trying to use pthread with mutex and cond variables to implement a garage. Normally I would just do it in main, but because I want to expand my C++ skills with OOP I want to implement it as a class.
First of all, I have some method that is called with threads. However, because of the way void* work in classes I have to implement them as static or functions outside of the class.
The problem is that it seems that the mutexes and condition variables wont communicate
void garage::start()
{
refresh = false;
pthread_create(&entryThread, nullptr, entryGuardThread, this);
for_each(carsThread.begin(), carsThread.end(), [&,this](pthread_t thread)
{
pthread_create(&thread, nullptr, &carThread, this);
});
}
This is in the class
void* carThread(void* in)
{
garage * temp = (garage*)in;
pthread_t uniqueThread = pthread_self();
while(!temp->refresh)
{
pthread_mutex_lock(&temp->entryLock);
temp->carWaitingAtEntry = true;
pthread_cond_signal(&temp->atEntry);
while(!temp->entryOpen)
pthread_cond_wait(&temp->atEntry, &temp->entryLock);
temp->carWaitingAtEntry = false;
pthread_mutex_unlock(&temp->entryLock);
temp->waiting(1);
}
return nullptr;
}
void* entryGuardThread(void* in)
{
garage * temp = (garage*)in;
while(!temp->refresh) {
pthread_mutex_lock(&temp->entryLock);
while(!temp->carWaitingAtEntry)
pthread_cond_wait(&temp->atEntry, &temp->entryLock);
temp->entryOpen = true;
pthread_cond_signal(&temp->atEntry);
while(temp->carWaitingAtEntry)
pthread_cond_wait(&temp->atEntry, &temp->entryLock);
temp->entryOpen = false;
pthread_mutex_unlock(&temp->entryLock);
}
return nullptr;
}
Do note that the reason that the functions are implemented as friends of the class so that I can access the private variable (I know it is stupid, but I gotta get it to work first). I have tested it and both functions refer to the same garage object....
All help is appreciated.
The Thread freezes at
while(!temp->entryOpen)
pthread_cond_wait(&temp->atEntry, &temp->entryLock);

Related

Running a task in a separate thread which shold be able to stop on request

I am trying to design an infinite (or a user-defined length) loop that would be independent of my GUI process. I know how to start that loop in a separate thread, so the GUI process is not blocked. However, I would like to have a possibility to interrupt the loop at a press of a button. The complete scenario may look like this:
GUI::startButton->myClass::runLoop... ---> starts a loop in a new thread
GUI::stopButton->myClass::terminateLoop ---> should be able to interrupt the started loop
The problem I have is figuring out how to provide the stop functionality. I am sure there is a way to achieve this in C++. I was looking at a number of multithreading related posts and articles, as well as some lectures on how to use async and futures. Most of the examples did not fit my intended use and/or were too complex for my current state of skills.
Example:
GUIClass.cpp
MyClass *myClass = new MyClass;
void MyWidget::on_pushButton_start_clicked()
{
myClass->start().detach();
}
void MyWidget::on_pushButton_stop_clicked()
{
myClass->stop(); // TBD: how to implement the stop functionality?
}
MyClass.cpp
std::thread MyClass::start()
{
return std::thread(&MyClass::runLoop, this);
}
void MyClass::runLoop()
{
for(int i = 0; i < 999999; i++)
{
// do some work
}
}
As far as i know, there is no standard way to terminate a STL thread. And even if possible, this is not advisable since it can leave your application in an undefined state.
It would be better to add a check to your MyClass::runLoop method that stops execution in a controlled way as soon as an external condition is fulfilled. This might, for example, be a control variable like this:
std::thread MyClass::start()
{
_threadRunning = true;
if(_thread.joinable() == true) // If thr thread is joinable...
{
// Join before (re)starting the thread
_thread.join();
}
_thread = std::thread(&MyClass::runLoop, this);
return _thread;
}
void MyClass::runLoop()
{
for(int i = 0; i < MAX_ITERATION_COUNT; i++)
{
if(_threadRunning == false) { break; }
// do some work
}
}
Then you can end the thread with:
void MyClass::stopLoop()
{
_threadRunning = false;
}
_threadRunning would here be a member variable of type bool or, if your architecture for some reason has non-atomic bools, std::atomic<bool>.
With x86, x86_64, ARM and ARM64, however, you should be fine without atomic bools. It, however is advised to use them. Also to hint at the fact that the variable is used in a multithreading context.
Possible MyClass.h:
MyClass
{
public:
MyClass() : _threadRunning(false) {}
std::thread start();
std::thread runLoop();
std::thread stopLoop();
private:
std::thread _thread;
std::atomic<bool> _threadRunning;
}
It might be important to note that, depending on the code in your loop, it might take a while before the thread really stops.
Therefore it might be wise to std::thread::join the thread before restarting it, to make sure only one thread runs at a time.

Global State Mutex vs Lock

This question isn't specific to glfw, but it serves well to describe what I mean. In glfw, in order to start using any functions we need to call glfwInit() and when we no longer need to use them we call glfwTerminate(), I've been trying to come up with a way to wrap this around a RAII class, and I've found two useful ways to do it, but I'm not sure of the pros and cons of each one. In all of these I'm omitting the error-checking and the such, as they won't change the examples too much.
1: Using a Lock-like class
My first idea was to have a lock-like class that called glfwInit() at the beginning of it's lifetime and glfwTerminate() and the end, something like this:
struct GLFWLock
{
GLFWLock() { glfwInit(); }
~GLFWLock() { glfwTerminate(); }
}
I realized that if two of these classes were created, then glfwInit and glfwTerminate would be called twice, so I added a ref counter and I felt like this was a fairly complete solution, aside from making it thread-safe and possible others, but it would essentially be the same thing:
struct GLFWLock
{
static size_t ref_count; /* = 0 in .cpp */
GLFWLock() { if ( ref_count == 0 ) { glfwInit(); } ref_count++; }
~GLFWLock() { ref_count--; if ( ref_count == 0 ) { glfwTerminate(); } }
}
2: Using a Mutex-like class
After working with the previous model for a bit, I realized it is the same as a std::lock_guard with a mutex, in a way, so I thought I could make a mutex class and have the user do a lock_guard whenever they needed to use glfw, instead of offering just a lock.
I ended up coming up with this, which somewhat fits the concept of mutex according to the standard, ignoring a few of the formal requirements and focusing on what std::lock_guard will actually use:
struct GLFWMutex
{
static size_t ref_count; /* = 0 in the .cpp */
bool locked = false;
~GLFWMutex() { unlock(); }
void lock()
{
if ( !locked )
{
if ( ref_count == 0 ) { glfwInit(); }
ref_count++;
locked = true;
}
}
void unlock()
{
if ( locked )
{
locked = false;
ref_count--;
if ( ref_count == 0 ) { glfwTerminate(); }
}
}
};
And then use it with std::lock_guard whenever it's needed, like a normal mutex.
I can see using the lock-like class is less that you have to type, since you don't have to declare a mutex and a guard, but would the mutex-like class be more useful? Possibly after adding more member functions like try_lock(), owns_lock() and others? Or is there a better solution to encapsulate this behavior?
Edit 1:
The usage syntax I'd like for this shared state would be something like:
struct glfw_shared_state
{
static size_t ref_count; /* = 0 in .cpp */
glfw_shared_state() { if ( ref_count == 0 ) { glfwInit(); } ref_count++; }
~glfw_shared_state() { ref_count--; if ( ref_count == 0 ) { glfwTerminate(); } }
};
struct Game
{
/// While this Game object is alive, I want to share the state of glfw, so it isn't terminated
glfw_shared_state state;
(...)
};
Where every instance of game would up the ref_count by one, which would make glfw stay alive throughout game's whole lifetime, basically a shared_ptr, but for functions instead of an object
Edit 2:
As for the std::lock_guard, what I meant was something like the following:
/// This has an internal ref counter for how many threads are currently locking it
/// When it first starts with 0 threads and someone locks, it calls glfwInit()
/// Then everytime some other thread locks, it just ups the ref counter
/// After every thread using it has unlocked it and it's ref counter is 0, it calls glfwTerminate()
/// So this isn't locking anyway, it's just sharing a state
glfw_mutex global_glfw_mutex;
void draw()
{
/// Make sure glfw is alive during this draw function
std::lock_guard lock(global_glfw_mutex);
}
It's a bit convoluted, but it's essentially what I meant with the second example in the original post, I think that mutex and lock aren't appropriate words for this, but I think the comment convey the meaning I want the code to have, the 'lock' is just a shared_ptr essentially

Asynchronous function call, with a method to check progress

I need help to implement an asynchonous funtion call in C++. I am new to multithreading in C++.
There sould be two funtions: one to get the work started in another thread and one to check progress and if work has been finished.
I tried it with some code from different answers on this site, but it doesn't work.
int __stdcall Test::asyncStartWork()
{
asyncReady = false;
std::thread workThread = std::thread(&Test::doWork, this);
return 0;
}
int __stdcall Test::asyncGetProgress()
{
if (asyncReady = true)
{
workThread.join();
return 100;
}
else
{
return asyncProgress;
}
}
int __stdcall Test::doWork()
{
//do work and write progress to asyncProgress
//at the end
asyncReady = true
}
When calling asyncStartWork I get the following error:
In method Test::asyncStartWork(), you are defining a local variable workThread which is hiding your class member.
So in asyncGetProgress(), when calling workThread.join(), you're calling it for a thread object which does not represent a thread (see here).
This results in a std::system_error being thrown with error condition no_such_process. If your program is not catching exceptions, this would result in the process aborting.
Try removing the std::thread part in asyncStartWork(), e.g.
int __stdcall Test::asyncStartWork()
{
asyncReady = false;
workThread = std::thread(&Test::doWork, this);
return 0;
}
Also, the __stdcall's seem unnecessary.

C++ Critical Section not working

My critical section code does not work!!!
Backgrounder.run IS able to modify MESSAGE_QUEUE g_msgQueue and LockSections destructor hadn't been called yet !!!
Extra code :
typedef std::vector<int> MESSAGE_LIST; // SHARED OBJECT .. MUST LOCK!
class MESSAGE_QUEUE : MESSAGE_LIST{
public:
MESSAGE_LIST * m_pList;
MESSAGE_QUEUE(MESSAGE_LIST* pList){ m_pList = pList; }
~MESSAGE_QUEUE(){ }
/* This class will be shared between threads that means any
* attempt to access it MUST be inside a critical section.
*/
void Add( int messageCode ){ if(m_pList) m_pList->push_back(messageCode); }
int getLast()
{
if(m_pList){
if(m_pList->size() == 1){
Add(0x0);
}
m_pList->pop_back();
return m_pList->back();
}
}
void removeLast()
{
if(m_pList){
m_pList->erase(m_pList->end()-1,m_pList->end());
}
}
};
class Backgrounder{
public:
MESSAGE_QUEUE* m_pMsgQueue;
static void __cdecl Run( void* args){
MESSAGE_QUEUE* s_pMsgQueue = (MESSAGE_QUEUE*)args;
if(s_pMsgQueue->getLast() == 0x45)printf("It's a success!");
else printf("It's a trap!");
}
Backgrounder(MESSAGE_QUEUE* pMsgQueue)
{
m_pMsgQueue = pMsgQueue;
_beginthread(Run,0,(void*)m_pMsgQueue);
}
~Backgrounder(){ }
};
int main(){
MESSAGE_LIST g_List;
CriticalSection crt;
ErrorHandler err;
LockSection lc(&crt,&err); // Does not work , see question #2
MESSAGE_QUEUE g_msgQueue(&g_List);
g_msgQueue.Add(0x45);
printf("%d",g_msgQueue.getLast());
Backgrounder back_thread(&g_msgQueue);
while(!kbhit());
return 0;
}
#ifndef CRITICALSECTION_H
#define CRITICALSECTION_H
#include <windows.h>
#include "ErrorHandler.h"
class CriticalSection{
long m_nLockCount;
long m_nThreadId;
typedef CRITICAL_SECTION cs;
cs m_tCS;
public:
CriticalSection(){
::InitializeCriticalSection(&m_tCS);
m_nLockCount = 0;
m_nThreadId = 0;
}
~CriticalSection(){ ::DeleteCriticalSection(&m_tCS); }
void Enter(){ ::EnterCriticalSection(&m_tCS); }
void Leave(){ ::LeaveCriticalSection(&m_tCS); }
void Try();
};
class LockSection{
CriticalSection* m_pCS;
ErrorHandler * m_pErrorHandler;
bool m_bIsClosed;
public:
LockSection(CriticalSection* pCS,ErrorHandler* pErrorHandler){
m_bIsClosed = false;
m_pCS = pCS;
m_pErrorHandler = pErrorHandler;
// 0x1AE is code prefix for critical section header
if(!m_pCS)m_pErrorHandler->Add(0x1AE1);
if(m_pCS)m_pCS->Enter();
}
~LockSection(){
if(!m_pCS)m_pErrorHandler->Add(0x1AE2);
if(m_pCS && m_bIsClosed == false)m_pCS->Leave();
}
void ForceCSectionClose(){
if(!m_pCS)m_pErrorHandler->Add(0x1AE3);
if(m_pCS){m_pCS->Leave();m_bIsClosed = true;}
}
};
/*
Safe class basic structure;
class SafeObj
{
CriticalSection m_cs;
public:
void SafeMethod()
{
LockSection myLock(&m_cs);
//add code to implement the method ...
}
};
*/
#endif
Two questions in one. I don't know about the first, but the critical section part is easy to explain. The background thread isn't trying to claim the lock and so, of course, is not blocked. You need to make the critical section object crt visible to the thread so that it can lock it.
The way to use this lock class is that each section of code that you want serialised must create a LockSection object and hold on to it until the end of the serialised block:
Thread 1:
{
LockSection lc(&crt,&err);
//operate on shared object from thread 1
}
Thread 2:
{
LockSection lc(&crt,&err);
//operate on shared object from thread 2
}
Note that it has to be the same critical section instance crt that is used in each block of code that is to be serialised.
This code has a number of problems.
First of all, deriving from the standard containers is almost always a poor idea. In this case you're using private inheritance, which reduces the problems, but doesn't eliminate them entirely. In any case, you don't seem to put the inheritance to much (any?) use anyway. Even though you've derived your MESSAGE_QUEUE from MESSAGE_LIST (which is actually std::vector<int>), you embed a pointer to an instance of a MESSAGE_LIST into MESSAGE_QUEUE anyway.
Second, if you're going to use a queue to communicate between threads (which I think is generally a good idea) you should make the locking inherent in the queue operations rather than requiring each thread to manage the locking correctly on its own.
Third, a vector isn't a particularly suitable data structure for representing a queue anyway, unless you're going to make it fixed size, and use it roughly like a ring buffer. That's not a bad idea either, but it's quite a bit different from what you've done. If you're going to make the size dynamic, you'd probably be better off starting with a deque instead.
Fourth, the magic numbers in your error handling (0x1AE1, 0x1AE2, etc.) is quite opaque. At the very least, you need to give these meaningful names. The one comment you have does not make the use anywhere close to clear.
Finally, if you're going to go to all the trouble of writing code for a thread-safe queue, you might as well make it generic so it can hold essentially any kind of data you want, instead of dedicating it to one specific type.
Ultimately, your code doesn't seem to save the client much work or trouble over using the Windows functions directly. For the most part, you've just provided the same capabilities under slightly different names.
IMO, a thread-safe queue should handle almost all the work internally, so that client code can use it about like it would any other queue.
// Warning: untested code.
// Assumes: `T::T(T const &) throw()`
//
template <class T>
class queue {
std::deque<T> data;
CRITICAL_SECTION cs;
HANDLE semaphore;
public:
queue() {
InitializeCriticalSection(&cs);
semaphore = CreateSemaphore(NULL, 0, 2048, NULL);
}
~queue() {
DeleteCriticalSection(&cs);
CloseHandle(semaphore);
}
void push(T const &item) {
EnterCriticalSection(&cs);
data.push_back(item);
LeaveCriticalSection(&cs);
ReleaseSemaphore(semaphore, 1, NULL);
}
T pop() {
WaitForSingleObject(semaphore, INFINITE);
EnterCriticalSection(&cs);
T item = data.front();
data.pop_front();
LeaveCriticalSection(&cs);
return item;
}
};
HANDLE done;
typedef queue<int> msgQ;
enum commands { quit, print };
void backgrounder(void *qq) {
// I haven't quite puzzled out what your background thread
// was supposed to do, so I've kept it really simple, executing only
// the two commands listed above.
msgQ *q = (msgQ *)qq;
int command;
while (quit != (command = q->pop()))
printf("Print\n");
SetEvent(done);
}
int main() {
msgQ q;
done = CreateEvent(NULL, false, false, NULL);
_beginthread(backgrounder, 0, (void*)&q);
for (int i=0; i<20; i++)
q.push(print);
q.push(quit);
WaitForSingleObject(done, INFINITE);
return 0;
}
Your background thread needs access to the same CriticalSection object and it needs to create LockSection objects to lock it -- the locking is collaborative.
You are trying to return the last element after popping it.

How to get pointer from another thread?

Let's have the following class definition:
CThread::CThread ()
{
this->hThread = NULL;
this->hThreadId = 0;
this->hMainThread = ::GetCurrentThread ();
this->hMainThreadId = ::GetCurrentThreadId ();
this->Timeout = 2000; //milliseconds
}
CThread::~CThread ()
{
//waiting for the thread to terminate
if (this->hThread) {
if (::WaitForSingleObject (this->hThread, this->Timeout) == WAIT_TIMEOUT)
::TerminateThread (this->hThread, 1);
::CloseHandle (this->hThread);
}
}
//*********************************************************
//working method
//*********************************************************
unsigned long CThread::Process (void* parameter)
{
//a mechanism for terminating thread should be implemented
//not allowing the method to be run from the main thread
if (::GetCurrentThreadId () == this->hMainThreadId)
return 0;
else {
m_pMyPointer = new MyClass(...);
// my class successfully works here in another thread
return 0;
}
}
//*********************************************************
//creates the thread
//*********************************************************
bool CThread::CreateThread ()
{
if (!this->IsCreated ()) {
param* this_param = new param;
this_param->pThread = this;
this->hThread = ::CreateThread (NULL, 0, (unsigned long (__stdcall *)(void *))this->runProcess, (void *)(this_param), 0, &this->hThreadId);
return this->hThread ? true : false;
}
return false;
}
//*********************************************************
//creates the thread
//*********************************************************
int CThread::runProcess (void* Param)
{
CThread* thread;
thread = (CThread*)((param*)Param)->pThread;
delete ((param*)Param);
return thread->Process (0);
}
MyClass* CThread::getMyPointer() {
return m_pMyPointer;
}
In the main program, we have the following:
void main(void) {
CThread thread;
thread.CreateThread();
MyClass* myPointer = thread.getMyPointer();
myPointer->someMethod(); // CRASH, BOOM, BANG!!!!
}
At the moment the myPointer is used ( in the main thread ) it crashes. I don't know how to get the pointer, which points to memory, allocated in another thread. Is this actually possible?
The memory space for your application is accessible to all threads. By default any variable is visible to any thread regardless of context (the only exception would be variables declared __delcspec(thread) )
You are getting a crash due to a race condition. The thread you just created hasn't started running yet at the point where you call getMyPointer. You need to add some kind of synchronization between the newly created thread and the originating thread. In other words, the originating thread has to wait until the new thread signals it that it has created the object.
I'm trying to get my head around what you are trying to do. It looks overly complicated for something like a thread-class. Would you mind post the class-definition as well?
Start by removing the C-style cast of the process-argument to CreateThread():
this->hThread = ::CreateThread (NULL, 0,&runProcess, (void *)(this_param), 0, &this->hThreadId);
If this doesn't compile you're doing something wrong! Never ever cast a function pointer! If the compiler complains you need to change your function, not try to cast away the errors! Really! You'll only make it worse for yourself! If you do it again they* will come to your home and do ... Let's see how you like that! Seriously, don't do it again.
Btw, in Process() I think it would be more appropriate to do something like:
assert(::GetCurrentThreadId() == hThreadId);
But if you declare it private it should only be accessible by your CThread-class anyway and therefor it shouldn't be a problem. Asserts are good though!
*It's not clear who they are but it's clear whatever they do it won't be pleasant!
As Rob Walker pointed out - I really missed the race condition. Also the crash is not when getting the pointer, but when using it.
A simple wait did the job:
MyClass* myPointer = thread.getMyPointer();
while (myPointer == 0)
{
::Sleep(1000);
}
myPointer->someMethod(); // Working :)