I've got 2 functions, func1() and func2(). func2 takes a character array as input. Both functions run on different threads. I call func2 from func1. When I passed a stack allocated array to func2, I got garbage values when I printed the array from inside func2(). However, when I passed a heap allocated array to func2, I got the correct string inside func2() i.e.
func2(char * char_array)
{
/* Some code */
cout<<char_array;
}
/* This does not work(Garbage values were printed in func2()) */
func1()
{
char array_of_char[SIZE];
memset(array_of_char,0,SIZE);
strncpy(array_of_char,"SOME_STRING",SIZE);
func2(array_of_char); //Asynchronous call to func2(). func1() proceeds immediately.
/*
some code
*/
}
/* This works(Correct values were printed in func2) */
func1()
{
char * array_of_char=new char[SIZE];
memset(array_of_char,0,SIZE);
strncpy(array_of_char,"SOME_STRING",SIZE);
func2(array_of_char); //Asynchronous call to func2(). func1() proceeds immediately.
/*
some code
*/
}
Does this mean that in multi-threaded programs, whenever some pointer has to be passed between different threads, the pointer should always be pointing at a heap-allocated memory?
Please note that func2() is actually a callback function which
executes on the occurrence of an event. I've hidden those details in
the question. Func1() does not stop/wait for the execution of func2().
Edit: I feel like I need to provide some more details of my implementation. In my program, I'm using Datastax C++ client library for Cassandra. Please find the link in the end, containing some details of the functions used in the program:
int main()
{
func1();
/* some code */
return 0;
}
/* This does not work(Garbage is printed in func2) */
void func1()
{
/* some code */
char array_of_char[SIZE];
memset(array_of_char,0,SIZE);
strncpy(array_of_char,"SOME_STRING",SIZE);
CassFuture* l_query_future = NULL;
/* some code where query is created */
l_query_future = cass_session_execute(rtGetSession(), l_stmt); //l_stmt is the query statement, rtgetSession() returns CassSession *
cass_future_set_callback ( l_query_future, func2, (void *)array_of_char); //details in the link given in the end
/* some code */
}
/* This works(Correct values were printed in func2) */
void func1()
{
/* some code */
char * array_of_char=new char[SIZE];
memset(array_of_char,0,SIZE);
strncpy(array_of_char,"SOME_STRING",SIZE);
CassFuture* l_query_future = NULL;
/* some code where query is created */
l_query_future = cass_session_execute(rtGetSession(), l_stmt); //l_stmt is the query statement, rtgetSession() returns CassSession *
cass_future_set_callback ( l_query_future, func2, (void *)array_of_char);
/*
some code
*/
}
void func2(CassFuture* l_query_future, void * data)
{
/* some code */
cout<<(char *)data;
}
References for Datastax driver APIs:
cass_future_set_callback
CassFuture
CassSession
cass_session_execute
How do you run func1() and func2() under different threads? func1() directly calls func2(), so they run under the same thread. Even the first implementation of func1() should work, as the array is still in its place.
EDIT:
But calling func2() directly from within func1() isn't an "asynchronous call to func2()" (even if at some other point it's used as a thread function). "Asynchronous call" means creating a new thread with func2() as the thread function. If so, this behaviour is very much expected, because func1() may have exited when func2() runs, and the array wouldn't exist by that time. On the other hand, the heap-block would still be allocated, so this would work. func2() should release the block then.
EDIT2:
Ummm, yes, the 2nd version is indeed an "asynchronous call to func2()", so the objects' lifetime considerations listed above indeed apply.
Does this mean that in multi-threaded programs, whenever some pointer has to be passed between different threads, the pointer should always be pointing at a heap-allocated memory?
No. This means that you must keep track of the lifetimes of your objects properly. When thread 1 finishes execution, the stack will be automatically cleaned up, thus spoiling the results that thread 2 is working with. Heap memory on the other hand stays if not explicitely freed. You have to check in thread 1 whether thread 2 is still executing and wait until it is finished, e.g. by using the join function.
No, the pointer does not have to point to heap-allocated memory, but you have to ensure the memory (in this case - an array) will be available until you join the thread.
Here, in the version that doesn't work, the array is allocated on the stack, and when the function func1 finishes, it is destroyed. Hence the rubbish values - likely something has written at that address slready.
To work around this, you could wait until the thread finishes in func1. The local variable would in this case be OK.
This code runs fine with the array allocated on the stack. As has been mentioned there is absolutely no threading happening here. To answer your question though, when passing pointers (or other data) between different threads (when you are actually using them) you would likely need some kind of synchronization such as a mutex or atomics, and of course ensure the lifetimes of any data.
Here is your code working,
#include <iostream>
#include <cstring>
using namespace std;
#define SIZE 20
void func2(char * char_array)
{
/* Some code */
cout<<char_array;
}
void func1()
{
char array_of_char[SIZE];
strncpy(array_of_char,"SOME_STRING",SIZE);
func2(array_of_char);
}
int main() {
func1();
return 0;
}
Demo
I should note that you are copying additional garbage by strncpy'ing SIZE into the array, you really just want to copy strlen("SOME_STRING").
Related
Our code has just started crashing due to a thread calling a memory alloc function and losing the pointer to the memory pool.
The pointer is initialised before the threads are started, but when the thread uses it to call the memory alloc code, it's zero.
In out init code we have
poolptr = InitMemoryPool ()
This sets it to a non zero memory address
In our .mm code on the thread we have
unsigned byte * p=(unsigned byte * ) MyAlloc ( poolptr, amount )
When the code gets into the MyAlloc function, poolptr is 0
Do I need my poolptr pointer to be volatile ? Even so, it's value is set up before the thread starts and never changes, so if the compiler is assuming it's a const, why doesn't it have it set correctly ?
Also, this has worked fine for years - and just started going wrong yesterday, simultaneously on two peoples machines.
Any ideas ?
This, what you mentioned, I don't do. What eventually worked for me is as follows:
I call my function or method and put in that function or method local instances of an class on the heap via command "new". Data that is to be returned is also paid respect to. Triggering a new thread will have access to that heap area if the heap area is a simple parameter. I.e., t= new thread( parameter);
void* function_or_method() {
clist *lstp;
string *_ps;
bool b;
try {
lstp= NULL;
lstp= new clist;
_ps= new string;
lstp->set( (void *)_ps);
mathclass *math;
thread *_thread;
math= new mathclass();
if((NULL==math))
throw Exception();
b= math->set( lstp);
if(! b) {
throw Exception();
}
_thread= new thread( math);
_thread->join();
delete _thread;
_thread= NULL;
} catch(const exception& e) {
clog <<"exception: logging" <<endl;
}
return (void*)lstp;
}
Okay, this is just C++ as well as C. I hope it will help a bit.
suppose I do the following :
void functionA(const char const input, int size)
{
char* dummyData = new char[size] ;
thread t(&functionB, dummyData);
t.detach();
}
void functionB(const char* data)
{
thread t2(&expendsiveFunction, data);
t2.join();
}
void expendsiveFunction(const char* data)
{
//do some expendsive stuff
delete[] data;
}
void main()
{
char* dataFromExternalSource; //lets assume this was provided from by an external soruce receive via TCP
functionA(dataFromExternalSource);
//do other stuff
}
I want the main thread to be available to do other stuff while I let the detached thread do the hard labour, in this scenario, am I right to say that dummyData will not go out of scope until expendsiveFunction() finishes?
any advise/comment would be helpful.
question 2: so even if i dont use thread.join() in function B, thread t will terminate at the end of expendsiveFunction() if functionB() just calls expendsiveFunction() ? (if functionB is part of another class..)
I'd say you are not right, since local variable dummyData goes out of scope when functionA finishes, and functionA will not wait for any other function or thread to finish.
The memory to which dummyData points, however, will remain valid since you allocate it dynamically using new[]. This memory is on the heap, and it will never "go out of scope" as it will never be popped from the stack; it will remain valid until you call delete[] somewhere in your code.
Note that only functionB and expensiveFunction hold a reference to this memory, so these functions are the only ones which can free this memory; if they don't, then you will have a memory leak.
BTW: your code does not compile; but that's not the question here.
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.
Some of functions in my program needs to run a long time so that the user may interrupted it. The structure is like this:
int MainWindow::someFunc1()
{
//VP is a class defined somewhere.
VP vp1;
//the for loop that needs time to execute.
return 0;
}
int MainWindow::someFunc2()
{
VP vp2;
//another loop that consumes time.
return 0;
}
If the user run the either of functions or at the same time and click exit on the right top, the program will still run in background until the loop is finished. I tried to free the resources in void closeEvent(QCloseEvent *) :
void MainWindow::closeEvent(QCloseEvent *)
{
vp.stopIt();
}
However since vp1 and vp2 are local variables, I don't know how to pass them into the closeEvent() function and free resources. Any suggestions will be appreciated.
Since the variables are created on the stack, they will be automatically freed in the end of their scope (at the closing } of the function in your case), you don't have to worry about them.
If you want to free them before the function ends, you need to re-implement the functions and probably allocate and free the memory for those variables by yourself, outside of the function. The way you pass them to the functions (either passing them as function arguments, or including them into the class) depends on you.
You can't. You should declare vp1 and vp2 in MainWindow as member variable.
As far as I understood the OP's requirement, he's looking how to interrupt someFunc1 or someFunc2 when the main window is closed.
Those functions run in the GUI thread, so the following statement is a misunderstanding
the program will still run in background until the loop is finished
What actually happens, the program runs until the function is complete, then the user action is processed by the framework. Therefore, when void MainWindow::closeEvent is executed, nothing is running in the background and resources are already freed.
OP should move someFunc1 and someFunc2 to a worker thread.
Theoretically, you might be able to do this using setjmp. Something along these lines:
#include "setjmp.h"
jmp_buf doNotAttempt;
jmp_buf badPractice;
int MainWindow::someFunc1()
{
VP vp1;
for (...) {
// do stuff
if (setjmp(doNotAttempt)) { /*free resources, then: */ longjmp(badPractice,1); }
}
return 0;
}
// [...]
void MainWindow::closeEvent(QCloseEvent *)
{
if (!setjmp(badPractice))
longjmp(doNotAttempt,1);
else
// do the same for your other loop
}
In practice, do not do this - it's a terrible idea for all kinds of reasons. As other folks have said, just declare vp1 and vp2 as member variables.
I have a program that processes neural spike data that is broadcast in UDP packets on a local network.
My current program has two threads a UI thread and a worker thread. The worker thread simply listens for data packets, parses them and makes them available to the UI thread for display and processing. My current implementation works just fine. However for a variety of reasons I'm trying to re-write the program in C++ using an Object Oriented approach.
The current working program initialized the 2nd thread with:
pthread_t netThread;
net = NetCom::initUdpRx(host,port);
pthread_create(&netThread, NULL, getNetSpike, (void *)NULL);
Here is the getNetSpike function that is called by the new thread:
void *getNetSpike(void *ptr){
while(true)
{
spike_net_t s;
NetCom::rxSpike(net, &s);
spikeBuff[writeIdx] = s;
writeIdx = incrementIdx(writeIdx);
nSpikes+=1;
totalSpikesRead++;
}
}
Now in my new OO version of the program I setup the 2nd thread in much the same way:
void SpikePlot::initNetworkRxThread(){
pthread_t netThread;
net = NetCom::initUdpRx(host,port);
pthread_create(&netThread, NULL, networkThreadFunc, this);
}
However, because pthead_create takes a pointer to a void function and not a pointer to an object's member method I needed to create this simple function that wraps the SpikePlot.getNetworSpikePacket() method
void *networkThreadFunc(void *ptr){
SpikePlot *sp = reinterpret_cast<SpikePlot *>(ptr);
while(true)
{
sp->getNetworkSpikePacket();
}
}
Which then calls the getNetworkSpikePacket() method:
void SpikePlot::getNetworkSpikePacket(){
spike_net_t s;
NetCom::rxSpike(net, &s);
spikeBuff[writeIdx] = s; // <--- SegFault/BusError occurs on this line
writeIdx = incrementIdx(writeIdx);
nSpikes+=1;
totalSpikesRead++;
}
The code for the two implementations is nearly identical but the 2nd implementation (OO version) crashes with a SegFault or BusError after the first packet that is read. Using printf I've narrowed down which line is causing the error:
spikeBuff[writeIdx] = s;
and for the life of me I can't figure out why its causing my program to crash.
What am I doing wrong here?
Update:
I define spikeBuff as a private member of the class:
class SpikePlot{
private:
static int const MAX_SPIKE_BUFF_SIZE = 50;
spike_net_t spikeBuff[MAX_SPIKE_BUFF_SIZE];
....
}
Then in the SpikePlot constructor I call:
bzero(&spikeBuff, sizeof(spikeBuff));
and set:
writeIdx =0;
Update 2: Ok something really weird is going on with my index variables. To test their sanity I changed getNetworkSpikePacket to:
void TetrodePlot::getNetworkSpikePacket(){
printf("Before:writeIdx:%d nspikes:%d totSpike:%d\n", writeIdx, nSpikes, totalSpikesRead);
spike_net_t s;
NetCom::rxSpike(net, &s);
// spikeBuff[writeIdx] = s;
writeIdx++;// = incrementIdx(writeIdx);
// if (writeIdx>=MAX_SPIKE_BUFF_SIZE)
// writeIdx = 0;
nSpikes += 1;
totalSpikesRead += 1;
printf("After:writeIdx:%d nspikes:%d totSpike:%d\n\n", writeIdx, nSpikes, totalSpikesRead);
}
And I get the following output to the console:
Before:writeIdx:0 nspikes:0 totSpike:0
After:writeIdx:1 nspikes:32763 totSpike:2053729378
Before:writeIdx:1 nspikes:32763 totSpike:2053729378
After:writeIdx:1 nspikes:0 totSpike:1
Before:writeIdx:1 nspikes:0 totSpike:1
After:writeIdx:32768 nspikes:32768 totSpike:260289889
Before:writeIdx:32768 nspikes:32768 totSpike:260289889
After:writeIdx:32768 nspikes:32768 totSpike:260289890
This method is the only method where I update their values (besides the constructor where I set them to 0). All other uses of these variables are read only.
I'm going to go on a limb here and say all your problems are caused by the zeroing out of the spike_net_t array.
In C++ you must not zero out objects with non-[insert word for 'struct-like' here] members. i.e. if you have an object that contains a complex object (a std string, a vector, etc. etc.) you cannot zero it out, as this destroys the initialization of the object done in the constructor.
This may be wrong but....
You seemed to move the wait loop logic out of the method and into the static wrapper. With nothing holding the worker thread open, perhaps that thread terminates after the first time you wait for a UDP packet, so second time around, sp in the static method now points to an instance that has left scope and been destructed?
Can you try to assert(sp) in the wrapper before trying to call its getNetworkSpikePacket()?
It looks like your reinterpret_cast might be causing some problems. When you call pthread_create, you are passing in "this" which is a SpikePlot*, but inside networkThreadFunc, you are casting it to a TetrodePlot*.
Are SpikePlot and TetrodePlot related? This isn't called out in what you've posted.
If you are allocating the spikeBuff array anywhere then make sure you are allocating sufficient storage so writeIdx is not an out-of-bounds index.
I'd also check that initNetworkRxThread is being called on an allocated instance of spikePlot object (and not on just a declared pointer).