I have a class and a library (lwip). For some reasons I need to call library's function of thread creation like :
/** The only thread function:
* Creates a new thread
* #param name human-readable name for the thread (used for debugging purposes)
* #param thread thread-function
* #param arg parameter passed to 'thread'
* #param stacksize stack size in bytes for the new thread (may be ignored by ports)
* #param prio priority of the new thread (may be ignored by ports) */
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int
stacksize, int prio);
Inside this function we call pthread:
code = pthread_create(&tmp,NULL,(void *(*)(void *)) function, arg);
My call looks like :
sys_thread_new("main_thread",(lwip_thread_fn)&this->main_thread, NULL,
DEFAULT_THREAD_STACKSIZE,DEFAULT_THREAD_PRIO);
My class method works fine, but I need to change some fielsd of CURRENT class (like 'state'
or else) I have an Idea to pass a pointer to current class to that thread and in thread function change class fields. Some kind of:
sys_thread_new("main_thread",(lwip_thread_fn)&this->main_thread, (void*)this,
DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
Then in main_thread:
void lwip::main_thread(void *arg) {
lwip *p = (lwip*)arg;
p->state = 1;
}
Something like that. But it seems I do something wrong -
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff6e8e700 (LWP 4985)]
0x0000000000403a75 in lwip::main_thread (this=0x7fffffffe4f0, arg=0x80) at
../src/lwip.cpp:50
50 p->state = 1;
There are two problems here: If the main_thread member function is a static member function, you pass a pointer to it using &lwip::main_thread, no casting should be needed. If the function is not static, then you must make it static.
The other problem is that if the instance (this) you pass to the thread function is destructed, the thread function now has a pointer to a destructed object. Be careful with temporary object or passing instances by value.
If the actual thread function can't be static, you can easily solve it with a static wrapper function:
class lwip
{
...
private:
void main_thread() { ... }
static void* main_thread_wrapper(void* arg)
{
reinterpret_cast<lwip*>(arg)->main_thread();
return nullptr;
}
};
...
sys_thread_new("main_thread", &lwip::main_thread_wrapper, this,
DEFAULT_THREAD_STACKSIZE,DEFAULT_THREAD_PRIO);
If you have to cast the pointer to function to get
pthread_create to compile, you have undefined behavior.
If the goal is to call a member function in a different thread,
you need to wrap the call in an extern "C" function. This
means no members and no templates; in the simplest case:
extern "C" void*
startThread( void* p )
{
static_cast<T*>(p)->f();
}
and pass the address of startThread as third argument and
a pointer to the object as fourth. If inheritance is involved,
you must ensure that the fourth argument has the same type as
that in the cast in startThread, e.g.:
pthread_create( &tmp, nullptr, &startThread, static_cast<Base*>( pointerToDerived ) );
if startThread casts to Base*.
If you need arguments to the function as well, you need to pass
a pointer to a struct with both the pointer to the object and
the additional arguments. You also need to ensure that the
lifetime of this struct is sufficient, so that there is no risk
of the thread accessing an already inexistant object. This
often means an additional conditional variable, to ensure that
the thread calling pthread_create doesn't continue before the
new thread has made a copy of all of the relevant data. (Both
Boost threads and the C++11 threads do this for you. It's only
necessary if you need additional data, other than just the
pointer to the object, in the new thread.)
This can get painful if you need to do it for many different
types, and downright impossible if the class in question is
a template. In such cases, one common solution is to use
a Thread object, along the lines of:
class Thread
{
public:
virtual void* run() = 0;
};
and a starter function:
namespace {
extern "C" void*
doStartThread( void* p )
{
return static_cast<Thread*>( p )->run();
}
}
pthread_t
startThread( Thread* thread )
{
pthread_t results;
if ( pthread_create( &results, nullptr, doStartThread, thread ) != 0 ) {
throw std::runtime_error( "Could not create thread" );
}
}
Afterwards, you inherit from Thread, overriding the run
function with whatever you want (and adding any additional data
you might need); the derived class can even be a template.
Again, the lifetime of the Thread object is an issue; the
solution I've usually used has been to require it to be
dynamically allocated, and then delete it at the end of
doStartThread. It's a very good idea to catch it in an
std::unique_ptr in doStartThread, although you still want to
catch exceptions in this function, since otherwise they will
kill the process. And don't forget the delete if
pthread_create fails (since the caller has passed over
ownership. If you really want to be sure:
namespace {
extern "C" void*
doStartThread( void* p )
{
std::unique_ptr<Thread*> object( static_cast<Thread*>( p ) );
try {
return object->run();
} catch ( ... ) {
return somethingElseToReportTheError;
}
}
}
pthread_t
startThread( std::unique_ptr<Thread> thread )
{
pthread_t results;
if ( pthread_create( &results, nullptr, doStartThread, thread.get() ) != 0 ) {
throw std::runtime_error( "Could not create thread" );
}
thread.release(); // AFTER the call has succeeded!
}
I've used this technique successfully in a number of
applications (using std::auto_ptr, since there was no
std::unique_ptr then); typically, the fact that you need to
use dynamic allocation is not an issue, and it solves the
lifetime issue quite nicely. (The alternative would be to use
a conditional variable, blocking the original thread until the
new thread had copied everything over.)
Note that by using a unique_ptr in the interface, you
effectively block the calling thread from further access to the
thread object, by robbing it of its pointer to the object. This
offers an additional guarantee with regards to thread safety.
But of course, this additional guarantee (and the solution to
the lifetime issues) only applies to the Thread object itself,
and not to anything it might point to.
Related
I am not completely sure how to best title this question since I am not completely sure what the nature of the problem actually is (I guess "how fix segfault" is not a good title).
The situation is, I have written this code:
template <typename T> class LatchedSubscriber {
private:
ros::Subscriber sub;
std::shared_ptr<T> last_received_msg;
std::shared_ptr<std::mutex> mutex;
int test;
void callback(T msg) {
std::shared_ptr<std::mutex> thread_local_mutex = mutex;
std::shared_ptr<T> thread_local_msg = last_received_msg;
if (!thread_local_mutex) {
ROS_INFO("Mutex pointer is null in callback");
}
if (!thread_local_msg) {
ROS_INFO("lrm: pointer is null in callback");
}
ROS_INFO("Test is %d", test);
std::lock_guard<std::mutex> guard(*thread_local_mutex);
*thread_local_msg = msg;
}
public:
LatchedSubscriber() {
last_received_msg = std::make_shared<T>();
mutex = std::make_shared<std::mutex>();
test = 42;
if (!mutex) {
ROS_INFO("Mutex pointer is null in constructor");
}
else {
ROS_INFO("Mutex pointer is not null in constructor");
}
}
void start(ros::NodeHandle &nh, const std::string &topic) {
sub = nh.subscribe(topic, 1000, &LatchedSubscriber<T>::callback, this);
}
T get_last_msg() {
std::lock_guard<std::mutex> guard(*mutex);
return *last_received_msg;
}
};
Essentially what it is doing is subscribing to a topic (channel), meaning that a callback function is called each time a message arrives. The job of this class is to store the last received message so the user of the class can always access it.
In the constructor I allocate a shared_ptr to the message and for a mutex to synchronize access to this message. The reason for using heap memory here is so the LatchedSubscriber can be copied and the same latched message can still be read. (the Subscriber already implements this kind of behavior where copying it doesn't do anything except for the fact that the callback stops being called once the last instance goes out of scope).
The problem is basically that the code segfaults. I am pretty sure the reason for this is that my shared pointers become null in the callback function, despite not being null in the constructor.
The ROS_INFO calls print:
Mutex pointer is not null in constructor
Mutex pointer is null in callback
lrm: pointer is null in callback
Test is 42
I don't understand how this can happen. I guess I have either misunderstood something about shared pointers, ros topic subscriptions, or both.
Things I have done:
At first I had the subscribe call happening in the constructor. I think giving the this pointer to another thread before the constructor has returned can be bad, so I moved this into a start function which is called after the object has been constructed.
There are many aspects to the thread safety of shared_ptrs it seems. At first I used mutex and last_received_msg directly in the callback. Now I have copied them into local variables hoping this would help. But it doesn't seem to make a difference.
I have added a local integer variable. I can read the integer I assigned to this variable in the constructor from the callback. Just a sanity check to make sure that the callback is actually called on an instance created by my constructor.
I think I have figured out the problem.
When subscribing I am passing the this pointer to the subscribe function along with the callback. If the LatchedSubscriber is ever copied and the original deleted, that this pointer becomes invalid, but the sub still exists so the callback keeps being called.
I didn't think this happened anywhere in my code, but the LatcedSubscriber was stored as a member inside an object which was owned by a unique pointer. It looks like make_unique might be doing some copying internally? In any case it is wrong to use the this pointer for the callback.
I ended up doing the following instead
void start(ros::NodeHandle &nh, const std::string &topic) {
auto l_mutex = mutex;
auto l_last_received_msg = last_received_msg;
boost::function<void(const T)> callback =
[l_mutex, l_last_received_msg](const T msg) {
std::lock_guard<std::mutex> guard(*l_mutex);
*l_last_received_msg = msg;
};
sub = nh.subscribe<T>(topic, 1000, callback);
}
This way copies of the two smart pointers are used with the callback instead.
Assigning the closure to a variable of type boost::function<void(const T)> seems to be necessary. Probably due to the way the subscribe function is.
This appears to have fixed the issue. I might also move the subscription into the constructor again and get rid of the start method.
I am working on a school project (simulation of virtual memory), where we are supposed to use detached threads. There are also other limitations to what we can use but I will mention that later. The problem is that when I give the pthread_create function the last argument as (void*)something and the created thread is detached, the function called by pthread_create will recieve the argument, but since the thread is detached, the original arguments are deleted as soon as the function from where I called pthread_create finishes - that means the argument in the called function is no longer valid and therefore I get segmentation faults etc.. Here is a part of the code (cant post it whole, its very big):
bool CProcManager::NewProcess(void* processArg, void(*entryPoint)(CCPU*, void*), bool copyMem) {
uint32_t free_page;
pthread_attr_t attr;
pthread_t thread;
if (proc_cnt >= 63)
return 0;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if (!FindFreePage(free_page)) return 0;
free_page = (free_page << 12) | 7;
CProcManager ccpu(m_MemStart, free_page);
ThrArgs args(entryPoint, (void *) processArg, ccpu);
proc_cnt++;
if (pthread_create(&thread, NULL, StartWork, (void *) &args))
return 0;
//pthread_mutex_lock(&start_mtx);
//pthread_cond_wait(&start_cond, &start_mtx);
//pthread_mutex_unlock(&start_mtx);
return 1;
}
Here you can see that this function gets a poitner to void and a pointer to function as parameters. pthread_creates tells the thread to call the "StartWork" function with argument "args", which is a structure containing a pointer to function, a pointer to void and an object of type CProcManager.
void* CProcManager::StartWork(void* arguments) {
//pthread_mutex_lock(&start_mtx);
ThrArgs *args = (ThrArgs*) arguments;
CProcManager ccpu = args->ccpu;
//pthread_cond_signal(&start_cond);
//pthread_mutex_unlock(&start_mtx);
args->entryPoint(&ccpu, args->processArg);
ccpu.RemovePage((ccpu.m_PageTableRoot >> 12) * PAGE_SIZE, false);
pthread_mutex_lock(&end_mtx);
proc_cnt--;
pthread_cond_signal(&end_cond);
pthread_mutex_unlock(&end_mtx);
return (NULL);
}
In this function, I finally call the function I had a pointer to. As you can guess, the arguments become invalid when the "NewProcess" function ends, so I tried to overcome this by adding a condition variable and somehow make a copy of the arguments I have (havent come to a solution yet) and then let the "NewProcess" function end. But there are certain limitations in this project. The function "NewProcess" is being called many times and the threads should run simultaneously (I tried signaling the condition variable after calling entryPoint and that worked), so I cant finish one thread and then do the next. The parameter "void* processArg" of the first function is originally a certain object type and this type cannot be accessed from the two functions above.
So can anyone please give me a suggestion how copy the arguments so I dont have a segmantation fault?
The problem is very simple and is one of object lifetimes and ownership.
You are passing the address of 'args' to the thread, but 'args' is created on the stack and goes out of scope soon after the thread has been started.
do it something like this:
// note: The ThrArgs constructor should take ownership of processArg
std::unique_ptr<ThrArgs> args (new ThrArgs(entryPoint, (void *) processArg, ccpu));
if (pthread_create(&thread, NULL, StartWork, (void *) args.get())) {
args.release();
// ownership of the pointer now belongs to the thread
return 0;
}
then in the thread function:
void* CProcManager::StartWork(void* arguments) {
std::unique_ptr<ThrArgs> args (reinterpret_cast<ThrArgs*>(arguments));
// now use args as a pointer
....
// the arguments will be deleted here
return 0;
}
There are two solutions. The simplest is often just to allocate
the arguments dynamically: in NewProcess:
ThrArgs* args = new ThrArgs( entryPoint, processArg, ccpu );
bool results = pthread_create( &thread, NULL, StartWork, args ) == 0;
if (!results) {
delete args;
}
(You could use std::unique_ptr or std::auto_ptr here as
well. In which case, don't call release on it unless
pthread_create succeeds!)
The alternative is to create a conditional variable over
a boolean, then wait on it before leaving the function, and copy
the parameters and then set the boolean in the new thread: in
NewProcess:
pthread_mutex_lock( &theMutex );
freeToContinue = false;
bool results = pthread_create( &thread, NULL, StartWork, args ) == 0;
if ( results ) {
while ( !freeToContinue ) {
pthread_cond_wait( &theCond, &theMutex );
}
pthread_mutex_unlock( &theMutex );
}
return results;
and in StartWork (the function you pass to pthread_create
must be extern "C", and so cannot be a member):
void* StartWork( void* arguments )
{
pthread_mutex_lock( &theMutex );
ThrArgs args = *static_cast<ThrArgs*>( arguments );
freeToContinue = true;
pthread_cond_broadcast( &theCond );
pthread_mutex_unlock( &theMutex );
// ...
}
(Obviously, I've left out a lot of error checking here.)
Either way: you may have to do something similar with regards to
the processArg argument, since its lifetime is determined by
that of the caller.
And you don't need all of the casts to void*.
It is my understanding that the function called when starting a thread inside an object should not be a class member. The best approach seems to be to launch a friend function, which gets you access back into your object.
In general, the member function (and therefore, the parent thread) that launched the daughter thread can continue or it can return. In every case where I use this technique, I let the launcher method just return to the app in the parent thread that called it; something like Qt threads.
When the daughter thread has finished its work, the final thing it does is return into the friend function which itself returns to something waiting to catch its return (pthread_koin or WaitForSingleEvent) or, if there is no catcher, I guess you'd say it returns to nowhere.
So, here is the question. If there is no catcher for the return from the friend function, that is, the parent thread is not in a member function, can I safely destroy the object that launched the child thread from the friend function?
EDIT --------------------------------------------------------------------------
Obvious from the responses, I need an example. We'll go for Windows. Not that different from Linux. I have left out lots of stuff, the class definition, etc.
Main creates so, a SomeObject on the heap.
Main calls so->run() and goes off to do other stuff.
Run() launches the daughter thread that runs SomeFriend().
SomeFriend() calls so->Worker() (that == so)
Worker() does whatever and returns to SomeFriend().
CAN I DELETE so HERE? i.e. delete that <<<=== the subject of this question.
SomeFriend() returns terminating the daughter thread.
//=================================================================
int main( int argc, char** argv )
{
SomeObject* so = new SomeObject();
so->run();
while(1)
{
DoOtherTasks(); // but don't exit!
}
return 0;
//=================================================================
void SomeObject::run();
(
volatile DWORD ThreadId; // Thread ID
HANDLE threadHandle;
try
{
threadHandle = CreateThread(
NULL, // default security attributes
0, // set stack size: default = 0
(LPTHREAD_START_ROUTINE)(SomeFriend),
(LPVOID*)this, // func args: this
0, // default creation flags
(LPDWORD)(&ThreadId) // ptr to thread identifier
);
}
catch ( ... )
{ throw; }
} // launches the thread and returns.
//=================================================================
void* SomeFriend( void* thisPtr ) // is a friend of SomeObject
{
SomeObject* that ((SomeObject*)thisPtr);
that->Worker();
// HERE IS WHERE THE QUESTION IS TALKING ABOUT
// CAN I DO THIS SAFELY?
delete that;
return (void*)NULL;
}
//=================================================================
void SomeObject::Worker() // remember, this is run in the daughter thread.
{
// whatever
return (void*)NULL;
}
To answer your edited question, yes you can delete that; However, remember that main() or any functions it calls might not have a valid so at any point in its logic after so->run() was called because of the way the thread scheduler may have scheduled the threads.
Think of the thread as "owning" so after you've called so->run(). main() and its stack descendants should never touch so again without guarded logic.
Yes.
Your memory management code should be thread-safe already (or threading would be dangerous to start with!) so the free() itself should be fine. The destruction is fine as well, as long as you keep in mind that nobody else may have a reference to this object as they will be pointing to a destructed object.
The reason that people say that it should not be a class member is that member functions have a typically hidden pointer that's also treated differently on a byte level from other parameters, so you can't just call it as a normal function with an extra parameter. This makes it typically incompatible with the pthread_create and CreateThreadEx functions that have a specific calling convention they want. That's why you have a bouncer static / global / friend function that does this calling convention conversion for you (and probably so transparently that you don't notice it yourself).
There's no inherent reason for not launching a member function as the top-level function in a thread. C++11 handles it just fine:
struct S {
void f();
};
S s;
int main() {
std::thread thr(&S::f, s);
thr.join();
return 0;
}
Here is the issue that I'm having with multithreading. The proc needs to be static which means the only way I see that 2 threads can communicate and share data is through the global scope. This does not seem very clean nor does it feel very OO. I know I can create a static proc function in a class but that's still static.
What I'd like to for example do is have thread procs in the class somehow so that ex: I could create an MD5 checksum class and have an array of these objects, each on their own thread checking its hash, while the UI thread is not impaired by this and another class could simply keep track of the handles and wait for multiple objects before saying "Complete" or something. How is this limitation usually overcome?
You cannot avoid using a static function if you want to start a thread there. You can however (using Windows) pass the this pointer as a parameter and use it on the other side to enter the class instance.
#include <windows.h>
class Threaded {
static DWORD WINAPI StaticThreadEntry(LPVOID me) {
reinterpret_cast<Threaded*>(me)->ThreadEntry();
return 0;
}
void ThreadEntry() {
// Stuff here.
}
public:
void DoSomething() {
::CreateThread(0, 0, StaticThreadEntry, this, 0, 0);
}
};
In C++, Boost.Thread solves the problem nicely. A thread is represented by a functor, meaning that the (non-static) operator() is the thread's entry point.
For example, a thread can be created like this:
// define the thread functor
struct MyThread {
MyThread(int& i) : i(i) {}
void operator()(){...}
private:
int& i;
};
// create the thread
int j;
boost::thread thr(MyThread(j));
by passing data to the thread functor's constructor, we can pass parameters to the thread without having to rely on globals. (In this case, the thread is given a reference to the integer j declared outside the thread.)
With other libraries or APIs, it's up to you to make the jump from a (typically static) entry point to sharing non-static data.
The thread function typically takes a (sometimes optional) parameter (often of type void*), which you can use to pass instance data to the thread.
If you use this to pass a pointer to some object to the thread, then the thread can simply cast the pointer back to the object type, and access the data, without having to rely on globals.
For example, (in pseudocode), this would have roughly the same effect as the Boost example above:
void MyThreadFunc(void* params) {
int& i = *(int*)params;
...
}
int j;
CreateThread(MyThreadFunc, &j);
Or the parameter can be a pointer to an object whose (non-static) member function you wish to call, allowing you to execute a class member function instead of a nonmember.
I'm not sure I understood well... I give it a try. Are you looking for thread local storage ?
Thread creation routines usually allow you to pass a parameter to the function which will run in a new thread. This is true for both Posix pthread_create(...) and Win32 CreateThread(...). Here is a an example using Pthreads:
void* func (void* arg) {
queue_t* pqueue = (queue_t*)arg;
// pull messages off the queue
val = queue_pull(pqueue);
return 0;
}
int main (int argc, char* argv[]) {
pthread_t thread;
queue_t queue = queue_init();
pthread_create(&thread, 0, func, &queue);
// push messages on the queue for the thread to process
queue_push(&queue, 123);
void* ignored;
pthread_join(&thread, &ignored);
return 0;
}
No statics anywhere. In a C++ program you could pass a pointer to an instance of a class.
I'm working with a C++ class-library that provides a Thread base-class where the user has to
implement a run() method.
Is there a recommended way on how to pass parameters to that run() method? Right now
I prefer to pass them via the constructor (as pointers).
I'm not sure about C++, but that's how you would do it in Java. You'd have a class that extends Thread (or implements Runnable) and a constructor with the parameters you'd like to pass. Then, when you create the new thread, you have to pass in the arguments, and then start the thread, something like this:
Thread t = new MyThread(args...);
t.start();
Must be the same in your case.
An alternative is to extend this Thread class to accept a functor as only constructor parameter, so that you can bind any call inside it.
Then the class using threads wont need to inherit from Thread, but only have one (or more) Thread member. The functor calls any start point you want ( some method of the class with any parameters )
Here is a typical pattern:
1) Define a data structure that encapsulates all the data your thread needs
2) In the main thread, instantiate a copy of the data structure on the heap using operator new.
3) Fill in the data structure, cast the pointer to void*, pass the void* to the thread procedure by whatever means you are provided by your thread library.
4) When the worker thread gets the void*, it reinterpret_cast's it to the data structure, and then takes ownership of the object. Meaning when the thread is done with the data, the thread deallocates it, as opposed to the main thread deallocating it.
Here is example code you can compile & test in Windows.
#include "stdafx.h"
#include <windows.h>
#include <process.h>
struct ThreadData
{
HANDLE isRunning_;
};
DWORD WINAPI threadProc(void* v)
{
ThreadData* data = reinterpret_cast<ThreadData*>(v);
if( !data )
return 0;
// tell the main thread that we are up & running
SetEvent(data->isRunning_);
// do your work here...
return 1;
}
int main()
{
// must use heap-based allocation here so that we can transfer ownership
// of this ThreadData object to the worker thread. In other words,
// the threadProc() function will own & deallocate this resource when it's
// done with it.
ThreadData * data = new ThreadData;
data->isRunning_ = CreateEvent(0, 1, 0, 0);
// kick off the new thread, passing the thread data
DWORD id = 0;
HANDLE thread = CreateThread(0, 0, threadProc, reinterpret_cast<void*>(data), 0, &id);
// wait for the worker thread to get up & running
//
// in real code, you need to check the return value from WFSO and handle it acordingly.
// Here I assume the retval is WAIT_OBJECT_0, indicating that the data->isRunning_ event
// has become signaled
WaitForSingleObject(data->isRunning_,INFINITE);
// we're done, wait for the thread to die
WaitForSingleObject(thread, INFINITE);
CloseHandle(thread);
return 0;
}
A common problem with thread startup is that the arguments passed exist on only the stack in the calling function. Thread startup is often deferred, such that the calling function returns and it is only some time later the thread actually starts - by which time the arguments are no longer in existence.
One solution to this is to create an event and then start the thread, passing the event as one of the arguments. The starting function then waits on the event, which is signalled by the thread when it has completed startup.
You can pass the parameters as members of the thread class. The thread which creates the thread can presumably call other methods and/or call member functions before the thread starts. Therefore it can populate whatever members are necessary for it to work. Then when the run method is called, it will have the necessary info to start up.
I am assuming that you will use a separate object for each thread.
You would normally put all the threads you create into an array, vector etc.
It is ok to pass them via constructor. Just be sure that pointers will live longer than the thread.
Well, I'd prefer to put the parameters in the Start() method, so you can have a protected constructor, and doesn't have to cascade the parameters through derived class constructor.
I'd prolly let my decleration look something like this:
class Thread
{
public:
virtual void Start(int parameterCount, void *pars);
protected:
Thread();
virtual void run(int parameterCount, void *pars) = 0;
}
Just make sure that your parameters are somehow contracted, e.g. #1 will be int, #2 will be a double etc. etc. :)