Lets say there are 4 consumer threads that run in a loop continuously
function consumerLoop(threadIndex)
{
int myArray[100];
main loop {
..process data..
myArray[myIndex] += newValue
}
}
I have another monitor thread which does other background tasks.
I need to access the myArray for each of these threads from the monitor thread.
Assume that the loops will run for ever(so the local variables would exist) and the only operation required from the monitor thread is to read the array contents of all the threads.
One alternative is to change myArray to a global array of arrays. But i am guessing that would slow down the consumer loops.
What are the ill effects of declaring a global pointer array
int *p[4]; and assigning each element to the address of the local variable by adding a line in consumerLoop like so p[threadIndex] = myArray and accessing p from monitor thread?
Note: I am running It in a linux system and the language is C++. I am not concerned about synchronization/validity of the array contents when i am accessing it from the monitor thread.Lets stay away from a discussion of locking
If you are really interested in the performance difference, you have to measure. I would guess, that there are nearly no differenced.
Both approaches are correct, as long as the monitor thread doesn't access stack local variables that are invalid because the function returned.
You can not access myArray from different thread because it is local variable.
You can do 1) Use glibal variable or 2) Malloca and pass the address to all threads.
Please protect the critical section when all threads rush to use the common memory.
Related
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.
I have in a Server object multiple thread who are doing the same task. Those threads are init with a Server::* routine.
In this routine there is a infinite loop with some treatments.
I was wondering if it was thread safe to use the same method for multiple threads ? No wonder for the fields of the class, If I want to read or write it I will use a mutex. But what about the routine itself ?
Since a function is an address, those thread will be running in the same memory zone ?
Do I need to create a method with same code for every thread ?
Ps: I use std::mutex(&Server::Task, this)
There is no problem with two threads running the same function at the same time (whether it's a member function or not).
In terms of instructions, it's similar to if you had two threads reading the same field at the same time - that's fine, they both get the same value. It's when you have one writing and one reading, or two writing, that you can start to have race conditions.
In C++ every thread is allocated its own call stack. This means that all local variables which exist only in the scope of a given thread's call stack belong to that thread alone. However, in the case of shared data or resources, such as a global data structure or a database, it is possible for different threads to access these at the same time. One solution to this synchronization problem is to use std::mutex, which you are already doing.
While the function itself might be the same address in memory in terms of its place in the table you aren't writing to it from multiple locations, the function itself is immutable and local variables scoped inside that function will be stacked per thread.
If your writes are protected and the fetches don't pull stale data you're as safe as you could possibly need on most architectures and implementations out there.
Behind the scenes, int Server::Task(std::string arg) is very similar to int Server__Task(Server* this, std::string arg). Just like multiple threads can execute the same function, multiple threads can also execute the same member function - even with the same arguments.
A mutex ensures that no conflicting changes are made, and that each thread sees every prior change. But since code does not chance, you don't need a mutex for it, just like you don't need a mutex for string literals.
Lets say i have A) Global variable B) Local variable but another thread has a ptr to it
Lets say i have this code
thread2(&localVar);//now thread2 can modify it
localVar=0;
globalVar=0;
while(1){
mutex.lock();
cout << (globalVar && localVar ? "Both true" : "fail");
mutex.unlock();
Sleep(1000)
}
Is this correct and safe? I can't remember. If it is my question is how does C++ know that localVar and globalVar may have been modified? If you say its because of mutex lock/unlock then my question is why? When calling any functions does C++ believe variables may have been modified and need to be reloaded into the register?
If this isn't safe then what makes it unsafe? (I suspect if it isnt then only localVar is unsafe), how do i correct it?
You are making a lot more complicated then it really is. Your responsibility is to make sure no conflicting accesses to a variable ever happen.
Definition: two accesses to a given memory location conflict iff they can happen concurrently and at least one is a write access.
So:
two writes to the same memory location = bad
a read and a write to the same memory location = bad
To ensure this never happens, you can use mutex, or you design your program so that variables shared between threads are only read. There are many other possible strategies.
If I understand your incomplete code correctly: localVar is modified concurrently in two threads. The behavior is not defined. Anything can happen.
It this correct and safe?
No.
Fix: Initialize localVar and globalVar before creating your second thread.
That you've exposed a localVar (on local stack? local var suggests on stack in scope) to another thread is troublesome. If this localVar is on the stack, then just be sure that you don't let it drop out of scope.
Are you using the same mutex on the other thread, to protect read/write access? If yes, then this is moving towards safe.
It's not a question of "does C++ know that localVar and globalVar may have been modified?": C++ doesn't know. For this situation, as described, it's all about using the mutex to properly protect all access to all shared values. The mutex, if used by both threads, allows only ONE thread at a time to get past it, into the protected code. Any other thread trying to lock the mutex will "stop & wait" until the lock is released.
So you're on the right track by surrounding your reads of the pair of values by the mutex.
When calling any functions does C++ believe variables may have been modified and need to be reloaded into the register?
As a general rule, yes.
I think that first time your get address of the local variable it become volatile and all reads and writes is performing with the memory.
This is a threading question where I basically started making a library thread-safe. My use-case is as follows -
struct <>
{
int thread_specific_value;
}
1) Spin 5 threads for example.
2) Each thread does operation and store thread_specific_value in the above data structure for example. This is dynamically allocated at the initialization of each thread and added to QThreadStorage.
3) Once all threads return to main thread, I like to access the errno values of all threads and do some processing. Before I delete the thread from the main thread, can I get the information of its storage data and store in main thread's specific storage.
In nutshell, how can I iterate through QThreadStorage of all the thread specific stored data and do some processing from main thread?
Data stored in QThreadStorage is accessible only from the thread that put it there. Period. If you want to access the same data from other threads, you must store it additionally elsewhere. In particular, the thread-specific value is destroyed on thread exit; if you want to keep the value, save it somewhere before the thread exits.
In short, don't try to use QThreadStorage for inter-thread communication. That's not what it's there for.
Sorry to reply on a question solved for over 9 years. I'm looking for a solution for a similar question like this one and I'm inspired by this sentence from the accepted answer by #bdonlan:
If you want to access the same data from other threads, you must store it additionally elsewhere.
So, instead of storing a copy elsewhere, you could just store the only copy elsewhere, i.e. in the main thread, collect all copies for different threads in a container (list or a map, but not a std::vector or QVector). Then, in each thread, the QThreadStorage stores a pointer to the copy in the main thread. Note, as long as the copy only get accessed by one thread, it's the same.
When a thread allocates a the data in the main thread's container, you'll still need a lock. But ongoing access won't need any lock.
In the end, all threads returns to the main thread, you can access the container lock free.
How do I use a boost::thread to execute a function with each thread executing in its own memory space. So that when I allocate a new variable with in the function it only lives as an instance in the executing thread.
Just to clarify I want to spawn threads that execute the same method using boost::thread but I do not want to use locks or semaphores I just want it to execute in a separate space.
Anything you allocate inside the thread function is already local to that function, as long as they're not declared as static. Just write your code as normal (avoiding static local variables) and you'll be fine.
If you need to create a thread that is running completely within its own address space, then what you are looking to do is to create a process, not a thread. Threads by definition are points of execution running within the same address space of the parent process.
If you really need to create threads (i.e. there's still memory and other resources shared between threads), but you also need to have a portion of memory dedicated to a specific thread, then you have few options:
1) as ildjarn suggested, have thread procedure allocate local (or dynamic memory) and write your code so that each thread uses this memory that it allocates for itself
2) Take a look at TLS (Thread Local Storage). It is an API that allows you to create "global" variables which are dedicated to a specific thread. Also some variations of C++ have built-in keywords for declaring variables which use TLS under the hood.
Note that in above options you will not get automatic isolation where a thread would not be able to corrupt another threads memory. The only way to get this isolation is to spawn multiple processes (or switch to one of .NET languages and instantiate multiple AppDomains running within the same process).