Why can't I kill pthread via class object argument passed in - c++

I initiate a background thread to run my class function, the task is executed as an infinite loop until client side decide to stop. So since when create pthread the class object 'this' is passed into thread, I tried to cast it to class object but get a null object, can anyone explain to me why this is not workable ?
void Camera::init()
{
typedef void *(*ThreadFuncPtr)(void *);
this->quit=false;
pthread_create(&acq, NULL, (ThreadFuncPtr)(&Camera::_acquireImages), this);
}
void Camera::stopAcquire()
{
this->quit=true;
}
void Camera::_acquireImages(void* ptr)
{
auto obj = (Camera*) ptr; //obj after cast shows as NULL object
while(!obj->quit){
//do something
}
pthread_exit(NULL);
}

So since when create pthread the class object 'this' is passed into
thread
pthread_create is a C function and expects the function signature to be void* (*)(void*) but it now has the signature void (Camera::*)(void*) so there are two errors: The function should return void* and it's also a non-static class member. To fix it, make the function return void* and make it static:
void Camera::init()
{
this->quit = false;
// now that the function has the correct signature, you don't need
// to cast it (into something that it wasn't)
pthread_create(&acq, NULL, &Camera::acquireImages, this);
}
void Camera::stopAcquire()
{
this->quit = true;
}
/*static*/ void* Camera::acquiredImages(void* ptr) // make it static in the declaration
{
Camera& obj = *static_cast<Camera*>(ptr);
while(obj.quit == false){
//do something
}
return nullptr;
}
If you are using C++11 (or newer), you should however take a look at the standard <thread> which makes life much easier.
#include <thread>
struct Camera {
void init() {
quit = false;
th = std::thread(&Camera::acquireImages, this);
}
~Camera() {
stopAcquire();
}
void acquireImages() {
// no need for casting. "this" points at the object which started the thread
while(quit == false) {
std::cout << ".";
}
}
void stopAcquire() {
if(th.joinable()) {
quit = true;
th.join(); // hang here until the thread is done
}
}
std::thread th{};
bool quit = false;
};

Related

What is the correct way of freeing std::thread* heap allocated memory?

I'm declaring a pointer to a thread in my class.
class A{
std::thread* m_pThread;
bool StartThread();
UINT DisableThread();
}
Here is how I call a function using a thread.
bool A::StartThread()
{
bool mThreadSuccess = false;
{
try {
m_pThread= new std::thread(&A::DisableThread, this);
mThreadSuccess = true;
}
catch (...) {
m_pDisable = false;
}
if(m_pThread)
{
m_pThread= nullptr;
}
}
return mThreadSuccess;
}
Here is the function called by my thread spawned.
UINT A::DisableThread()
{
//print something here.
return 0;
}
If I call this StartThread() function 10 times. Will it have a memory leak?
for (i = 0; i<10; i++){
bool sResult = StartThread();
if (sResult) {
m_pAcceptStarted = true;
}
}
What is the correct way of freeing
m_pThread= new std::thread(&A::DisableThread, this);
The correct way to free a non-array object created using allocating new is to use delete.
Avoid bare owning pointers and avoid unnecessary dynamic allocation. The example doesn't demonstrate any need for dynamic storage, and ideally you should use a std::thread member instead of a pointer.
If I call this StartThread() function 10 times. Will it have a memory leak?
Even a single call will result in a memory leak. The leak happens when you throw away the pointer value here:
m_pThread= nullptr;
could you add your better solution
Here's one:
auto future = std::async(std::launch::async, &A::DisableThread, this);
// do something while the other task executes in another thread
do_something();
// wait for the thread to finish and get the value returned by A::DisableThread
return future.get()
I'd personally would prefer using a threadpool in a real project but this example should give you an idea of how you could handle threads without new/delete.
#include <iostream>
#include <thread>
#include <vector>
class A
{
public:
template<typename Fn>
void CallAsync(Fn fn)
{
// put thread in vector
m_threads.emplace_back(std::thread(fn));
}
~A()
{
for (auto& thread : m_threads)
{
thread.join();
}
}
void someHandler()
{
std::cout << "*";
};
private:
std::vector<std::thread> m_threads;
};
int main()
{
A a;
for (int i = 0; i < 10; ++i)
{
a.CallAsync([&a] { a.someHandler(); });
}
}

Callable function C++

I've read various answer on SO and still didn't understood how I should make an object method to be callable in this case:
Considering:
Class A
{
void generator(void)
{
int i = 1;
while(1)
{
if(i == 1)
{
one(/***/);//Should be a flag
i = 2;
}
else
{
two(/**/);//Should be a flag
i = 1;
}
}
}
template <typename CallbackFunction>
void one(CallbackFunction&& func)
{
}
template <typename CallbackFunction>
void two(CallbackFunction&& func)
{
}
A()
{
std::thread t(&A::generator, this);
t.detach();
}
};
and a simple main file:
void pOne(/**/)
{
std::cout<<"1"<<std::endl;
}
void pTwo(/**/)
{
std::cout<<"2"<<std::endl;
}
A myA;
A.One(pOne);
A.Two(pTwo);
int main(int argc, char** argv)
{
while(1){}
}
Here are where I'm at:
generator() should update a flag, and both one() & two() should poll on that flag & loop forever.
One() (two() also) should have a function pointer as parameters and if necessary other parameters, pOne() should have the same parameters except the function pointer.
So my questions are:
1) Is my understanding correct?
2) Is there a clean way to make generator() to start one() or two() ? (flags, semaphore, mutex, or anything that is a standard way to do it)
3) Assuming that the code was working, is it behaving as I expect ? i.e. printing 1 and 2?
if it matters, I'm on ubuntu
Disclaimer 1: Like everyone else, I'm interpreting the question as:
-> You need an event handler
-> You want callback methods on those events
And the only reason I think that is because I helped you on a i2c handler sequence before.
Also, there are better logic than this, its provided following your stubs "rules".
You mentioned that you are on Ubuntu, so you will be lacking windows event system.
Disclaimer 2:
1- To avoid going to deep I'm going to use a simple way to handle events.
2- Code is untested & provided for logic only
class Handler
{
private:
std::mutex event_one;
event_one.lock();
void stubEventGenerator(void)
{
for(;;)
{
if(!event_one.try_lock())
{
event_one.unlock();
}
sleep(15); //you had a sleep so I added one
}
}
template <typename CallbackFunction>
void One__(CallbackFunction && func)
{
while(1)
{
event_one.lock();
func();
}
}
public:
Handler()
{
std::thread H(&Handler::stubEventGenerator, this);
}
~Handler()
{
//clean threads, etc
//this should really have a quit handler
}
template <typename CallbackFunction>
void One(CallbackFunction && func) //I think you have it right, still I'm not 100% sure
{
std::thread One_thread(&Handler::One__, this, func); //same here
}
};
Some points:
One() as to be a wrapper for the thread calling One__() if you want it to be non-blocking.
mutex can be a simple way to handle events as long as the same event doesn't occur during its previous occurence (you are free to use a better/more suitable tool for your use case, or use boost:: only if necessary)
Prototype of One() & One__() are probably wrong, that's some research for you.
Finally: How it works:
std::mutex.lock() is blocking as long as it can't lock the mutex, thus One__ will wait as long as your event generator won't unlock it.
Once unlock One__ will execute your std::function & wait for the event (mutex) to be raised (unlock) again.
far from a perfect answer, but lack of time, and not being able to put that in a comment made me post it, will edit later
With whatever limited information you provided this code can be made compilable in following manner:
#include <iostream>
#include <thread>
typedef void(*fptr)();
void pOne(/**/)
{
std::cout<<"1"<<std::endl;
}
void pTwo(/**/)
{
std::cout<<"2"<<std::endl;
}
class A
{
public:
void generator(void)
{
int i = 1;
while(1)
{
if(i == 1)
{
fptr func = pOne;
one(func);//Should be a flag
i = 2;
}
else
{
fptr func = pTwo;
two(func);//Should be a flag
i = 1;
}
}
}
template <typename CallbackFunction>
void one(CallbackFunction&& func)
{
func();
}
template <typename CallbackFunction>
void two(CallbackFunction&& func)
{
func();
}
A()
{
std::thread t(&A::generator, this);
t.detach();
}
};
int main()
{
A myA;
while(1)
{
}
return 0;
}
If you want that one and two should accept any type/number of arguments then pass second argument as variadic template.Also I could not understand why you want one and two to be called from main as your generator function is for this purpose only and this generator function is called from thread which is detached in class constructor

How to multithreading a class member function with pthreads?

I'm trying to run a function named extensionStep from a class named SVAnchor in multi threads. i use this code:
rc = pthread_create(&threads[i], NULL, extensionStep, &td[i]);
to call the function and here is the definition of extensionStep :
void* SVAnchor::extensionStep( void *threadarg)
and i got the following error:
error: cannot convert 'SVAnchor::extensionStep' from type 'void* (SVAnchor::)(void*)' to type 'void* (*)(void*)'
rc = pthread_create(&threads[i], NULL, extensionStep, &td[i]);
^
that shows the problem is converting from type 'void* (SVAnchor::)(void*)' to type 'void* ()(void)'
How to solve this problem?
Thanks all
This should do the job: (After making the function extensionStep static)
rc = pthread_create(&threads[i], NULL, &(SVAnchor::extensionStep), &td[i]);
Or you can create a wrapper function like this:
struct Argument {
SVAnchor* ptr;
int* tid;
}
static void *extensionStepWrapper(void *arg)
{
return (((Argument*)arg)->ptr)->extensionStep(((Argument*)arg)->tid);
}
And use the wrapper:
Argument arg;
arg.ptr = &(class_variable_name); // Use appropriate name (whatever you variable name is for the object of the class SVAnchor)
arg.tid = &(td[i]);
rc = pthread_create(&threads[i], NULL, &(SVAnchor::extensionStepWrapper), &arg);
Note that if you're calling this from inside another member function, you may do this instead:
arg.ptr = this;
You can also create a method in the class to start the thread:
bool StartThread(int* tid){
return (pthread_create(&_thread, NULL, extensionStep, tid) == 0);
}
You might also need to pass the thread as argument of StartThread() function.
This is a common mapping of a class member function to a C-callback:
#include <iostream>
#include <pthread.h>
class Task
{
public:
Task() : thread_id(0) {}
bool start() {
// Passing this as user data to the C-callback.
return pthread_create(&thread_id, 0, invoke, this) == 0;
}
void stop() {
void* no_result;
pthread_join(thread_id, &no_result);
}
private:
Task(const Task&); // no copy (C++11 delete)
Task& operator = (const Task&); // no copy (C++11 delete)
void process() {
std::cout << "Hello\n";
}
// The C-callback has to be static.
static void* invoke(void* self) {
// Note: The invocation takes place in start (passing this)
static_cast<Task*>(self)->process();
// No result passed to join.
return 0;
}
pthread_t thread_id;
};
int main() {
Task task;
task.start();
task.stop();
}
This is a C++11 version:
#include <iostream>
#include <thread>
class Task
{
public:
void operator () () {
std::cout << "Hello\n";
}
};
int main() {
Task task;
std::thread thread(task);
thread.join();
}

std::vector of std::functions find

I have a vector populated with callback functions and I would like to check whether callback to the function already exists prior to adding it. I don't know whether it will even work bu so far it doesn't even compile.
vector<std::function<void(void*)>> _callbacks;
void Event::RegisterCallback(std::function<void(void*)> callback)
{
if (callback == NULL)
return;
vector<std::function<void(void*)>>::iterator it = std::find(_callbacks.begin(), _callbacks.end(), callback);
if (it == _callbacks.end())
{
_callbacks.push_back(callback);
}
else
{
//print error
throw;
}
}
This gives a compile error:
"Overload resolution selected deleted operator '=='" in alorithm(805). This is related to the find function call.
How do I get this to work and is it even going to compare function calls to the same method properly?
Thanks
As noted in the comments the simplest solution is to use default C-style function pointers as they support == operator in opposite to C++11 function which does not.
using func_type = void(*)();
vector<func_type> _callbacks;
void Event::RegisterCallback(func_type callback)
{
if (callback == nullptr)
return;
auto it = std::find(_callbacks.begin(), _callbacks.end(), callback);
if (it == _callbacks.end()) {
_callbacks.push_back(callback);
}
else {
throw;
}
}
void f() {};
void g() {};
/*
evt.RegisterCallback(f); // works fine
evt.RegisterCallback(g); // works fine
evt.RegisterCallback(f); // throws exception
*/
If you don't like this approach you can write your own function-pointer class with support of equality operator.
Another solution is to have a class with a std::function member and another comperable member, and then overloading the () to get the std::function parameter and call it with the parameter, and the == operator to compeare the class using the comperable member.
CompareableFunction.h:
class CompareableFunction
{
public:
CompareableFunction(int nId, std::function<void(parameter)> handler);
~CompareableFunction();
void operator()(parameter param);
bool operator== (CompareableFunction compareableFunc);
private:
std::function<void(parameter)> m_handler;
int m_nId;
};
CompareableFunction.cpp:
CompareableFunction::CompareableFunction(int nId, std::function<void(parameter)> handler)
{
m_nId = nId;
m_handler = handler;
}
CompareableFunction::~CompareableFunction()
{
}
void CompareableFunction::operator()(parameter param)
{
return m_handler(param);
}
bool CompareableFunction::operator==(CompareableFunction compareableFunc)
{
return (m_nId == compareableFunc.m_nId);
}
EDIT: you can convert the std::function to a C-style function pointer and use it to compare. example to a conversion is here: http://www.cplusplus.com/forum/general/63552/

Passing a member function as parameter of a member function

I'm busy with making a leveleditor class in an engine but I'm stuck at passing a member function as parameter of another member function.
First I've made a typedef
typedef void (LevelEditor::*CallFunctionPtr)();
Then I have made a member function to check if the user clicks with his mouse on a hitregion. If so, another function needs to be called. So I've my first member function with 2 parameters
LevelEditor.h
void CheckClickCollision(HitRegion* region, CallFunctionPtr callFunctionPtr);
LevelEditor.cpp
void LevelEditor::CheckClickCollision( HitRegion* region, CallFunctionPtr callFunctionPtr)
{
if(GAME_ENGINE->GetLButtonMouseState())
{
if(!m_bIsLeftPressed && region->HitTest(m_MousePosition))
(this->*callFunction)();
m_bIsLeftPressed = true;
}
else
m_bIsLeftPressed = false;
}
Then I've two stupid example member functions:
LevelEditor.h
void LevelUp();
void LevelDown();
LevelEditor.cpp
void LevelEditor::LevelUp()
{
++m_iCurrentLevel;
}
void LevelEditor::LevelDown()
{
if(m_iCurrentLevel > 0)
--m_iCurrentLevel;
else
return;
}
And now I want to call that function every tick to check if there is a hit. So in my tick function:
CheckClickCollision(m_LeftArrowRegionPtr, LevelDown);
CheckClickCollision(m_RightArrowRegionPtr, LevelUp);
And here I get the error on LevelDown and Levelup:
Error: argument of type void (LevelEditor::*)()" is incompatible with parameter of type "CallFunctionPtr *"
Dont know how to fix it. Tried different things, nothing worked
Try
CheckClickCollision(m_LeftArrowRegionPtr, &LevelEditor::LevelDown);
CheckClickCollision(m_RightArrowRegionPtr, &LevelEditor::LevelUp);
For your convenience, here's the working sample (the compiler is GCC 4.7):
#include <stdio.h>
class LevelEditor;
typedef void (LevelEditor::*CallFunctionPtr)();
class LevelEditor
{
public:
LevelEditor() {}
void CheckClickCollision(void* region, CallFunctionPtr callFunction)
{
(this->*callFunction)();
}
void LevelUp() { printf("up\n"); }
void LevelDown() { printf("down\n"); }
void Test()
{
CheckClickCollision(NULL, &LevelEditor::LevelDown);
CheckClickCollision(NULL, &LevelEditor::LevelUp);
}
};
int main()
{
LevelEditor e;
e.Test();
return 0;
}
The other way to call this:
void Test()
{
CallFunctionPtr p;
p = &LevelEditor::LevelDown;
CheckClickCollision(NULL, p);
p = &LevelEditor::LevelUp;
CheckClickCollision(NULL, p);
}
You need to use std::function and std::bind, or lambdas if you have a supporting compiler.
void LevelEditor::CheckClickCollision( HitRegion* region, std::function<void()> callFunction)
{
if(GAME_ENGINE->GetLButtonMouseState())
{
if(!m_bIsLeftPressed && region->HitTest(m_MousePosition))
callFunction();
m_bIsLeftPressed = true;
}
else
m_bIsLeftPressed = false;
}
void Test()
{
// lambda
CheckClickCollision(NULL, [this] { LevelDown(); });
// bind
CheckClickCollision(NULL, std::bind(&LevelEditor::LevelDown, this));
}