What happens when a thread's void pointer is changed during runtime? - c++

I began learning about POSIX threads recently, and I've learned that when you have two threads Main and B, thread B can continuously change a variable in thread Main if I reference the variable as the void pointer in thread B's creation.
That lead me to wonder how to make thread Main continuously change a variable in thread B. I wrote a program to test whether changing the sent parameter changes thread B by running thread B and then changing the referenced variable. It didn't do anything. Is this result right?
So basically:
void *someFunc(void *var) {
int *num=(int*) var;
int num2=*num;
while (true) {
if (num2==1) {
*num=3;
} else {
*num=5;
}
}
return NULL;
}
someVar=1;
pthread_t threadB;
if(pthread_create(&threadB, NULL, someFunc , &someVar)) {
return 1;
}
someVar=2;
//then join both threads later and print someVar
//will someVar be 3 or 5?
Basically, when I reference a variable using the void pointer in thread creation, will any future changes to that variable affect the newly created thread? If this is not true, in order to continuously change it, is there some particular call for that? Should I look into locks/mutex or just put someFunc into a class and change its initializer variables?
Thanks!

The line
int num2=*num;
Creates a copy of the number pointed to by the main thread. You have a race, therefore: if it is changed before the copy, one thing will happen; otherwise, the child thread will never see the change.

Because you pass someVar by pointer to someFunc, and then you copy it to the pointer num, any change to someVar will immediately change the value of *num.
But num2 will not be affected by changes to someVar, because num2 is a a different variable allocated don the stack of thread B. Therefore, the outcome of the while loop will be determined by the value that was assigned to num2 when the thread started. This can be either 1 or 2, depending on how fast the main thread and thread B are running. Such a dependency is a non-deterministic behavior called a "race condition", and you need to be very careful to avoid it.

Related

Can the thread object be deleted after std::thread::detach?

I have a question about std::thread::detach(). In cplusplus.com it says 'After a call to this function, the thread object becomes non-joinable and can be destroyed safely', by which it seems to mean that the destructor ~thread() may be called safely.
My question is, does this mean that it is ok & safe to delete a thread object immediately after calling detach(), as in the following sample code? Will the function my_function continue safely, and safely use its thread_local variables and variables that are global to the program?
#include <thread>
#include <unistd.h>
void my_function(int t)
{
sleep(t);
}
int main()
{
std::thread *X = new std::thread(my_function, 10);
X->detach();
delete X;
sleep(30);
return 0;
}
The code 'runs' ok, I just want to know if this is safe from the point of view of memory ownership. My motivation here is to have a program that runs 'forever', and spawns a few child threads from time to time (e.g. every 30 seconds.) Each child thread then does something, and dies: I do not want to have to somehow keep track of the children in the parent thread, call join() and then delete.

multithreading thread switching issue

I have a producer and consumer thread that are being created from main. They perform correctly well, except for the cout statement
class myclass{
int x;
// stuff
}
void foo1(myclass* ob){
setX(ob->x);
// stuff
}
void foo2(myclass* ob){
cout << ob->x << endl; // ONLY THIS DOESN'T EXECUTE
ob->getX();
// stuff
}
int main(){
myclass* ob = new myclass();
boost::thread producer_thread(boost::bind(foo1, ob));
boost::thread consumer_thread(boost::bind(foo2, ob));
// stuff
producer_thread.join();
consumer_thread.join();
}
Everything works fine (including showX that displays x, except for the cout. What's wrong?
Your threads are sharing the object without actually any lock on it. producer is not exiting before consumer started accessing the object.
Using producer_thread.join() before boost::thread consumer_thread(boost::bind(foo2, ob)) should resolve this, which is not the best fix. Using mutex locks will be ideal.
Adding to the previous answer, you can also use a state variable or condition variable to ensure that your object is not getting written upon / processed by a thread when some other thread is working on it. In other words, you can have a state variable whose value is changed by each function to a unique number upon completion and each function will start operating when the state variable is assumes the value that the previous function is supposed to set it to.

Join threads in a() that were created in a previous call of a(). Is this possible?

SOLVED / SHORT ANSWER: Yes you can. Bug was somewhere else. Read on if you want to know where it was.
I have to process items (do calculations that are independent between items). Items are processed in a function a();
What i want to do is whenever a() is called, create a new thread with all a()'s processing code in it, and immediately exit a(). Next time a() will be called (is called immediately by the caller which i don't have access to), will again create a new thread and terminate. When 8 consequent calls have been made (i have 8 cores), inside a() join the 8 previous threads and go on...
Is this possible? Can i join inside a() threads that have been created in a previous call of a()?
My program, while it runs perfectly for 1 thread, it faults in any other number.
=================================================================================
ADDED CODE FOR YOU TO SEE:
First of all. I don't have access to the function that calls a(). if no threading is involved, caller waits until a() finishes it's calculations, and then calls it again providing the next x,y* s. What i want to do is doing parallel the calculations of 8 a()s. If a() can start its calculations and return (create a thread and exit), caller will call a() again with the new x,y* while the old are still being calculated. This is the concept. Calculations of every x,y* pair is totally independent to any other pair.
int counter = 0;
pthread_t threads[8]; //i have 8 cores
thread_args args[8]; //arguments that pass to the threads
int res[8]; //threads store their results here
void a(int x, int y*) { //a() is being called by caller immediately after it returns with a new pair of x,y*
args[counter].x = x; //struct thread_args has x,y,my_counter
args[counter].y = y;
args[counter].my_counter = counter;
pthread_create(&threads[counter], NULL, calculate_xy, (void *)&args[counter]);
//calculate_xy stores results in res[args->my_counter]
if(++counter != 8)
return;
//it reaches here every 8th call of a(); (total number of a() calls is an exact multiple of 8)
counter = 0;
for (int i = 0; i < 8; ++i)
pthread_join(threads[i], NULL);
//GO ON... append the 8 results to a text and go on...
}//end a()
First of all, whatever the bug in your code, this is a bad design. Your function a() has global state (the past-created threads and the number created so far) which would be bad enough in a single-threaded program, but in a multi-threaded program, things could go very wrong if multiple threads could simultaneously call a(). Even if not, there are many reasons to avoid global state:
http://www.youtube.com/watch?v=-FRm3VPhseI
A much better design would be for the a() function to take an extra argument, a pointer to a structure containing the counter and an array of pthread_t values for all the threads created so far. Then, the "state of a()" would not be global state, but would be state belonging to the part of the program using a().
As for why your program is crashing right now, it's hard to say without seeing any code. I suspect you're either calling a() from multiple threads without synchronization, or just have a careless error/typo somewhere in your array indexing...
The answer to my original question is yes.
You can join threads in a function that were created in a previous call of this same function.
The bug in my code was that the place where y* pointed, was reused inside caller, every time a() was called. So, while i thought that previously created threads were still doing their job correctly, they were not because during their life, the place where y* argument was pointing was being repeatedly rewritten, at every new a() call from the caller with the contents of the next x,y* pair messing threads' calculations.
Thank you all. You guided me to solution.

c++ member function thread safe

I am writing a function for logging messages .
I will be calling this print function from different threads .
My code is as follows :
MyLog::printLog(const char* s)
{
std::string myline(s);
//m_Mutex is class member and there will be only object for this class
// shared by all threads
int ret = pthread_mutex_lock(&m_Mutex);
if ( ret != 0 )
{
std::cout<<" trying to lock same mutex char* "<<std::endl;
}
//code to log message in File
pthread_mutex_unlock(&m_Mutex);
}
My question is if above function is called from different threads with argument like "from thread1" , "from thread 2" ,... will there be any chance const char *s will be jumbled up printing wrong values .?
I hope my question is clear .
Your function will work as you expect, since myline is a local variable (each thread has its own stack, so would have its own instance of myline)
If you're calling this function from different threads, and any changes you make to your argument const char* s are protected by your mutex m_Mutex then you'll be just fine and nothing will be jumbled.
EDIT
Actually, each call to this function will have it's own stack when called from a different thread, and seeing that it const char* you cannot change your argument, so there's no need to protect it with a mutex.
Your variable s is a variable local to the thread it's being called in, and it's const.
Then copying into the local variable myline is definitely not going to mess with anything, cause each thread has it's call stack, on which lives an instance of myline when this function is called, which is totally separate and independent of any other thread.
It depends on how you are calling the printLog function. If the string whose address you pass to the function gets mutated by a different thread, then you may not see a consistent view of it inside the log function. If you pass in a pointer to an immutable string, like a literal for example, then you're fine, though.
Here's an example that's fine:
void from_thread_one()
{
MyLog::printLog("Hello World"); // immutable string
}
void from_thread_two()
{
MyLog::printLog("Another text"); // ditto
}
On the other hand, here's an example that's not OK and has a race:
char globalString[] = "This is a really long string";
void from_thread_one()
{
globalString[5] = 'A';
MyLog::printLog(globalString);
}
void from_thread_two()
{
globalString[8] = 'Q';
MyLog::printLog(globalString);
}
In this setting, you are making a copy of the string (via std::string myline(s);) while the contents of the array pointed to by s can simultaneously be changed in the other thread. In this scenario, dereferencing the char pointer has to happen inside the critical section as well.
The fundamental problem with your setup is that the raw char pointer has no implicit semantics that tell the user which behaviour is acceptable and which isn't. Had you passed in an actual std::string by value, you would have removed the uncertainty about synchronising access to the string from your printLog function and moved the responsibility entirely into the caller.

Thread-Safe implementation of an object that deletes itself

I have an object that is called from two different threads and after it was called by both it destroys itself by "delete this".
How do I implement this thread-safe? Thread-safe means that the object never destroys itself exactly one time (it must destroys itself after the second callback).
I created some example code:
class IThreadCallBack
{
virtual void CallBack(int) = 0;
};
class M: public IThreadCallBack
{
private:
bool t1_finished, t2_finished;
public:
M(): t1_finished(false), t2_finished(false)
{
startMyThread(this, 1);
startMyThread(this, 2);
}
void CallBack(int id)
{
if (id == 1)
{
t1_finished = true;
}
else
{
t2_finished = true;
}
if (t1_finished && t2_finished)
{
delete this;
}
}
};
int main(int argc, char **argv) {
M* MObj = new M();
while(true);
}
Obviously I can't use a Mutex as member of the object and lock the delete, because this would also delete the Mutex. On the other hand, if I set a "toBeDeleted"-flag inside a mutex-protected area, where the finised-flag is set, I feel unsure if there are situations possible where the object isnt deleted at all.
Note that the thread-implementation makes sure that the callback method is called exactly one time per thread in any case.
Edit / Update:
What if I change Callback(..) to:
void CallBack(int id)
{
mMutex.Obtain()
if (id == 1)
{
t1_finished = true;
}
else
{
t2_finished = true;
}
bool both_finished = (t1_finished && t2_finished);
mMutex.Release();
if (both_finished)
{
delete this;
}
}
Can this considered to be safe? (with mMutex being a member of the m class?)
I think it is, if I don't access any member after releasing the mutex?!
Use Boost's Smart Pointer. It handles this automatically; your object won't have to delete itself, and it is thread safe.
Edit:
From the code you've posted above, I can't really say, need more info. But you could do it like this: each thread has a shared_ptr object and when the callback is called, you call shared_ptr::reset(). The last reset will delete M. Each shared_ptr could be stored with thread local storeage in each thread. So in essence, each thread is responsible for its own shared_ptr.
Instead of using two separate flags, you could consider setting a counter to the number of threads that you're waiting on and then using interlocked decrement.
Then you can be 100% sure that when the thread counter reaches 0, you're done and should clean up.
For more info on interlocked decrement on Windows, on Linux, and on Mac.
I once implemented something like this that avoided the ickiness and confusion of delete this entirely, by operating in the following way:
Start a thread that is responsible for deleting these sorts of shared objects, which waits on a condition
When the shared object is no longer being used, instead of deleting itself, have it insert itself into a thread-safe queue and signal the condition that the deleter thread is waiting on
When the deleter thread wakes up, it deletes everything in the queue
If your program has an event loop, you can avoid the creation of a separate thread for this by creating an event type that means "delete unused shared objects" and have some persistent object respond to this event in the same way that the deleter thread would in the above example.
I can't imagine that this is possible, especially within the class itself. The problem is two fold:
1) There's no way to notify the outside world not to call the object so the outside world has to be responsible for setting the pointer to 0 after calling "CallBack" iff the pointer was deleted.
2) Once two threads enter this function you are, and forgive my french, absolutely fucked. Calling a function on a deleted object is UB, just imagine what deleting an object while someone is in it results in.
I've never seen "delete this" as anything but an abomination. Doesn't mean it isn't sometimes, on VERY rare conditions, necessary. Problem is that people do it way too much and don't think about the consequences of such a design.
I don't think "to be deleted" is going to work well. It might work for two threads, but what about three? You can't protect the part of code that calls delete because you're deleting the protection (as you state) and because of the UB you'll inevitably cause. So the first goes through, sets the flag and aborts....which of the rest is going to call delete on the way out?
The more robust implementation would be to implement reference counting. For each thread you start, increase a counter; for each callback call decrease the counter and if the counter has reached zero, delete the object. You can lock the counter access, or you could use the Interlocked class to protect the counter access, though in that case you need to be careful with potential race between the first thread finishing and the second starting.
Update: And of course, I completely ignored the fact that this is C++. :-) You should use InterlockExchange to update the counter instead of the C# Interlocked class.