Understanding OS dispatching between different processors - c++

If I have a class
class A{
A(){
getcontext(context);
makecontext(context, fun1, etc)
put context pointer on queue
}
fun1(args){
something
}
}
In I make an instance of class A in Thread1 running on CPU1, and then try to pop the context off the queue and swap it in from thread2 on CPU2, will there be a problem because the object was instantiated in the stack of Thread1 in CPU1 and hence the pointer to fun1 which is attacked to this context is not reachable?

I'd say the answer is yes and no. All threads share the same memory. If more than 1 thread accesses the object, you need to be careful to synchronize access between thread. That's the yes part.
The no part is when you said stack of thread 1. Stack variables are local to a function. If the function returns, the local variables are no longer valid. You don't show quite enough code for me to see where context gets created, and if the function that allocate the object on the stack waits until thread 2 finishes.

No. The whole point of threads is that they share all memory.

Related

Multiple threads inside class accessing data

I've read that different threads share the same memory segments apart from the stack. There is something i've been trying to understand. I have a class which creates different threads. Below is a simple example of what I am doing, creating one thread in the constructor.
When an object of this class is created, in main() for example, all the threads can access the same member variables. If every thread gets its own stack, why doesn't each thread get a copy of the member variables rather than access to the same variable. I have looked around and I'm trying to get a picture in my mind of what is going on in memory here with the different stack frames. Many thanks in advance for any replies.
////////////////////////
MyClass::MyClass()
{
t1 = std::thread([this] { this->threadFunc(); });
t1.detach();
}
/////////////////////////
void MyClass::threadFunc()
{
///do stuff.. update member variables etc.
}
I've read that different threads share the same memory segments apart
from the stack.
This is not entirely accurate. Threads share the same address space as opposed to being sand-boxed like processes are.
The stack is just some memory in your application that has been specifically reserved and is used to hold things such as function parameters, local variables, and other function-related information.
Every thread has it's own stack. This means that when a particular thread is executing, it will use it's own specific stack to avoid trampling over other threads which might be idle or executing simultaneously in a multi-core system.
Remember that these stacks are all still inside the same address space which means that any thread can access the contents of another threads' stack.
A simple example:
#include <iostream>
#include <thread>
void Foo(int& i)
{
// if thread t is executing this function then j will sit inside thread t's stack
// if we call this function from the main thread then j will sit inside the main stack
int j = 456;
i++; // we can see i because threads share the same address space
}
int main()
{
int i = 123; // this will sit inside the main threads' stack
std::thread t(std::bind(&Foo, std::ref(i))); // we pass the address of i to our thread
t.join();
std::cout << i << '\n';
return 0;
}
An illustration:
>
As you can see, each thread has its own stack (which is just some part of the processes' memory) which lives inside the same address space.
I've read that different threads share the same memory segments apart from the stack. [...] If every thread gets its own stack, why doesn't each thread get a copy of the member variables rather than access to the same variable.
Hmm... the short answer is, that's the purpose for which threads were designed: multiple threads of execution, all accessing the same data. Then you have threading primitives - like mutexes - to make sure that they don't step on each others' toes, so to speak - that you don't have concurrent writes, for example.
Thus in the default case, threads share objects, and you have to do extra work to synchronize accesses. If you want threads to each have copies of objects... then you can instead write the code to give each thread a copy of the object, instead of the same object. Or, you may consider using processes (e.g. via fork()) instead of threads.
If you have
MyClass c1;
MyClass c2;
then there will be two instances of MyClass, c1 and c2, each with its own members. The thread started during construction of c1 will have access to c1's members only and the thread started in c2 will have access to c2's members only.
If you are talking about several threads within one class (not obvious from your code), then each thread has a copy of this which is just a pointer to your MyClass object. New (local) variables will be allocated on the thread's stack and will be visible only for the thread which creates them.

Confused about pthreads

First, I am new to pthreads, so if I completely misunderstood, please just let me know.
I had searched for the proper method of returning values and came across this link How to return a value from thread in C and https://linuxprograms.wordpress.com/category/pipes/ .
So I can share locations controlled by the starting thread OR pipe information, but the last value can't be put on some stack? Why can't I return in the same way that a program does when called by a shell (such as bash)?
(From what I understand, it would be possible to have a regular return value if it was C++, but (according to something I read I think here perhaps https://computing.llnl.gov/tutorials/pthreads/) POSIX isn't completely defined for C++, just C.)
Take a look at pthread_exit and pthread_join.
When you are done with your thread you can call pthread_exit(void* retval)
The pthread_exit() function terminates the calling thread and returns
a value via retval that (if the
thread is joinable) is available to another thread in the same process that calls pthread_join(3).
This call to pthread_exit will stop your thread and, as it says, store the return value where pthread_join can get to it and place it in its second argument: int pthread_join(pthread_t thread, void **retval);
When you call pthread_join(tid, &returnVal); where tid is a pthread_t, returnVal will now hold a pointer to the value returned given to pthread_exit
This allows you to pass data out of threads on their exit.
Each thread has its own stack and local environment with the parent process. Your main process creates one thread (the main thread) and your code runs under it. Any other threads you create, get the same treatment: each gets a stack, a thread context, thread local storage (where applicable) and there is no common stack to return a value.
When you join a thread you started, what happens is you are actually waiting for it to finish executing. This will unblock the wait, but will not return any user value since typically, the thread, its stack, and all of its environment within the process is destroyed.
While threads are running, they can communicate with one another in the ways you mentioned, and they can also read/write to common memory locations as long as you use a synchronization mechanism to serialize those accesses.
If you must have a return value from your thread, then you might want to encapsulate it in a class, pass it the class instance on start, then just before the thread exits, it can leave a "return value" in a member of this class so you can examine it after the class "run" or "start" method (the one that actually runs the thread) returns.
Hope this helps.

Preventing variables from going out of scope so they persist for another thread

I have a function that creates a bunch of local variables, then passes their addresses to a function that runs in a separate thread - something like this:
void MyFunction()
{
MyClass a;
AnotherClass b;
...
FinalClass z;
CallFunctionInNewThread(&a,&b,&c,...,&z);
}
Of course, these variables are destroyed when the MyFunction goes out of scope (so the function in a thread is now pointing to garbage), so this setup doesn't work. What are my options here? If I allocate the variables on the heap with 'new', I will never get a chance to delete them. If I make them smart pointers or similar, I'd have to make the threaded function accept them as smart pointers, or their reference count will not be increased so they will still get destroyed immediately. It seems like they kind of want to be member variables of a wrapper class of MyFunction, but there are a few hundred lines and tens of these things and that would just be crazy messy. Are there any other choices?
Are there any other choices?
Simply copy (if trivial) or move/swap the data (if heavy to create) -- similar to transferring ownership from one thread to the other. Seems Thread A really does not need a reference from the description. Bonus: This removes concurrent access complexities from your program.
One little trick you can do is to pass a semaphore object into the thread function and then wait for that semaphore to be signaled. You do need to check that the thread was created successfully.
The new thread first makes local copies of the values (or references in the case of smart pointers), then signals the semaphore and carries on.
The calling thread can then continue and drop those objects off its stack without interfering with your new thread. It can even delete the semaphore object since it is no longer required by either thread.
It does mean that the calling thread has to wait until the thread is started and has copied its data, but that probably will be a short time. If you are going to the effort of spawning a thread to do any work at all, then this slight delay in the parent thread ought to be acceptable.

Is this safe across threads?

I have some code that looks like this:
Thread 0:
CMyOtherClass *m_myclass;
CMyClass::SomeFunc(DWORD SomeParam)
{
m_myclass = new CMyOtherClass(SomeParam);
}
Thread 1:
CMyClass::InsideSecondThread()
{
MySecondThreadFunc(*m_myclass);
}
CMyClass::MySecondThreadFunc(MyOtherClass& myclass)
{
// do something with myclass variable....
// What about thread safety??? Is this not now a shared variable?
// or have we passed a copy and are we safe?
// SomeParam should be the same while in this thread, however it can be changed by Thread 0
}
So my question is, if you are passing this m_myclass variable across threads, is this threadsafe or not?
It is not threadsafe.
It is not threadsafe.
If thread 1 gets executed before the thread 0 creates the object then you end up in accessing NULL pointer in thread 1. ( Assuming m_myclass is initialised to NULL in the constructor)
Another point is :
CMyClass::MySecondThreadFunc(MyOtherClass& myclass)
the myclass object is a shared object and any operations from different threads can create problem.
Unless there is a shared static member, local copy should work for thread safe here.
You can create a new CMyOtherThreadSafeClass which has two members
CMyOtherClass *m_myclass and a CRITICAL_SECTION cs. You should InitializeCriticalSection or better with InitializeCriticalSectionAndSpinCount function in the CMyOtherThreadSafeClass constructor and use EnterCriticalSection and LeaveCriticalSection (see http://msdn.microsoft.com/en-us/library/aa910712.aspx and http://msdn.microsoft.com/en-us/library/ms686908.aspx) everywhere if you need access CMyOtherClass *m_myclass member (read or modify, allocate or free).
You can include a method in CMyOtherThreadSafeClass to make easier to use of EnterCriticalSection and LeaveCriticalSection. If all threads of your program will use EnterCriticalSection and LeaveCriticalSection then your program will be thread safe.
If you call CMyClass::SomeFunc only prior to the second thread being created, then there is no race condition.
Otherwise, it's basically the same problem that prevents double-checked locking from working: The pointer could be assigned to m_myclass prior to the object actually being constructed, and the thread then uses an unconstructed (or partially constructed) object.
It's not threadsafe because both threads are accessing the same bit of memory.
As your code stands, as long as thread 0 allocates the memory before thread 1 starts then you should have no problems because thread 0 doesn't do anything except the allocation. If you change the thread 0 code so it starts modifying the class instance then you'll start to run into issues.
[Edit] Removed my example of what I thought ought to be thread-safe. There's another post here on SO which asks whether changing a pointer is considered an atomic action which is worth a read.

Is it safe to pass (synchronously) stack-allocated memory to other thread?

Recently I heard that memory in the stack is not shared with other thread and memory in the heap is shared with other threads.
I normally do:
HWND otherThreadHwnd;
DWORD commandId;
// initialize commandId and otherThreadHwnd
struct MyData {
int data1_;
long data2_;
void* chunk_;
};
int abc() {
MyData myData;
// initialize myData
SendMessage(otherThreadHwnd,commandId,&myData);
// read myData
}
Is it alright to do this?
Yes, it is safe in this instance.
Data on the stack only exists for the lifetime of the function call. Since SendMessage is a synchronous, blocking call, the data will be valid for the duration of that call.
This code would be broken if you replace SendMessage with a call to PostMessage, SendNotifyMessage, or SendMessageCallback, since they would not block and the function may have returned before the target window received the message.
I think 2 different issues are being confused by whoever you "heard that memory in the stack is not shared with other thread":
object lifetime - the data on the stack is only valid as long the thread doesn't leave the scope of the variable's name. In the example you giove, you're handling this by making the call to the other thread synchronously.
memory address visibility - the addresses pspace for a process is shared among the various threads in that process. So variables addressable by one thread are addressable by other threads in that process. If you are passing the address to a thread in a different process, the situation is quite different and you'd need to use some other mechanism (which might be to ensure that the memory block is mapped into both processes - but that I don't think that can normally be done with stack memory).
Yes, it is okay.
SendMessage is working in blocking mode. Even if myData is allocated in stack, its address is still visible to all threads in the process. Each thread has its own private stack; but data in the stack can be explicitly shared, for example, by your code. However, as you guess, do not use PostThreadMessage in such case.
What you heard about is "potential infringement of privacy", which is sharing the data on one thread's private stack with another thread.
Although it is not encouraged, it is only a "potential" problem--with correct synchronization, it can be done safely. In your case, this synchronization is done by ::SendMessage(); it will not return until the message is processed in the other thread, so the data will not go out of scope on the main thread's stack. But beware that whatever you do with this pointer in the worker thread, it must be done before returning from the message handler (if you're storing it somewhere, be sure to make a copy).
As others have said already, how you have it written is just fine, and in general, nothing will immediately fail when passing a pointer to an object on the stack to another thread as long as everything's synchronized. However, I tend to cringe a little when doing so because things that seem threadsafe can get out of their intended order when an exception occurs or if one of the threads is involved with asynchronous IO callbacks. In the case of an exception in the other thread during your call to SendMessage, it may return 0 immediately. If the exception is later handled in the other thread, you may have an access violation. Yet another potential hazard is that whatever's being stored on the stack can never be forcibly disposed of from another thread. If it gets stuck waiting for some callback, object, etc, forever and the user has decided to cancel or quit the application, there is no way for the working thread to be sure the stalled thread has tidied up whatever objects are on its stack.
My point is this: In simple scenarios as you've described where everything works perfectly, nothing ever changes, and no outside dependencies fail, sharing pointers to the local stack is safe - but since allocating on the heap is really just as simple, and it gives you the opportunity to explicitly control the object's lifetime from any thread in extenuating circumstances, why not just use the heap?
Finally, I strongly suggest that you be very careful with the void* chunk_ member of your MyData structure, as it is not threadsafe as described if it's copied in the other thread.