c - global variables in pthreads - c

Suppose I defined a function in file function.c, and in main.c I create multiple pthreads to execute the function in function.c.
If in function.c, I define a global variable, for example, int foo;
Then, my question is, does every thread has its own instance of this variable "foo" or do they share a single "foo"?

They share a single foo variable. Global variable always exists only once per process and is usually protected by mutex to avoid concurrent access.
Since C11 you can use thread_local to declare the variable as local per thread:
#include <threads.h>
...
thread_local int perThreadInt;

A global varariable is a variable whose scope is within the entire *.c file. They can be accessible wherever they use in same file.
Threads are lightweight process but
in multi-threaded process (or a multi-threaded file) all threads work together to provide different-2 functionality for related process.
So, because they're not stand-alone process so they access global variable in a global manner.
Local variables defined in pthreads are locally accessible in the thread in which they are declared.
Any thread doesn't know about local variable of another thread .

Related

Is it preferred to use a global pthread_mutex_t in C projects?

How is pthread_mutex_t used for a multi source C project.
Is there a global pthread_mutex_t in a header file or does each source file defines it's own?
How many times pthread_mutex_init is used? only once per mutex?
So if we use a global mutex, we only need to use pthread_mutex_init once in the beginning of main?
How is pthread_mutex_t used for a multi source C project.
It really depends on the project itself and what the code needs to do. There's no "standard" way of doing this.
Is there a global pthread_mutex_t in a header file or does each source file define it's own?
Again, it depends on what is needed. There is no rule saying that there should only be one global mutex or that there should be one mutex per source file. It depends. If a resource needs to be managed by different files then a unique global mutex can be used. If another resource needs to be managed only by the code that is defined in a single source file then there's no need to make it available globally (and it can be defined static).
Yes, pthread_mutex_init should be used once per mutex.
So if we use a global mutex, we only need to use pthread_mutex_init once in the beginning of main?
Yes. That would be one way to do it.
Another, perhaps better approach is to just initialize the variable at its definition:
pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER;
// or
static pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER;
This way there's no need to call pthread_mutex_init and you don't risk forgetting it.
Generally, you should expect to use one mutex for each "unit" of shared state that's accessed by multiple threads. If one such unit is global state, then you would expect to have a global mutex alongside it, and it can be statically initialized with PTHREAD_MUTEX_INITIALIZER. If it's a data structure that can exist in multiple instances in allocated storage, you normally want to place the mutex protecting it inside the data structure itself, and initialize it with pthread_mutex_init when it's created, before its existence is exposed to multiple threads.

Is shared library local variable thread safe?

I'm developing a multi-threaded application which application which will access a shared library, now i see that the shared library doesn't contain any global variable, so does it mean that the library is thread safe? for example.
I'm calling function func() from various threads to a shared library like:
thread 1 -> func()
thread 2 -> func()
...
thread N ->func()
and the func() is defined as below,
void func(){
int var;
func2(&var);
}
In this cases, will it be thread safe?
The usage that you are showing is thread-safe, because invocations of func from each thread will have their own copy of the variable var.
This is not a guarantee, though, for several reasons:
Library needs to be careful about its use of static variables as well. If you replace int var with static int var, func would not longer be thread-safe
You need to be careful about calling the library. If the same pattern that you show is present in your code, i.e. if your code shares a local variable among threads, the code would not be thread-safe.
The library may use functions that are not thread-safe, such as strtok. Using these functions makes your library not thread-safe.
Yes, the code in question will execute in the context of each thread, and the local automatic variable will typically be stored on each thread's stack.

How to cleanly instantiate a global mutex that is shared by threads in one of the threads itself

I use GLib/GObject and am facing the following problem:
I have a class my_class that will have several object instances in multiple threads during runtime, where each object will exist within a single thread (so there is a 1:1 relation between the thread and the object).
However, the object will access a shared resource and I need locking to protect access to that resource. Now, I need a global mutex (a GMutex in GLib world) instance, that is available to all threads/objects to lock onto.
My current approach is to create that mutex before the threads are spawned, and pass that global mutex along in the constructor. But I don't like that approach. The mutex is not of any concern of the calling code before creating the threads - it is only required for functionality by the my_class and should as such then only be part of the my_class for a clean OO design.
But how to create a single mutex from within my_class? I could create a static GMutex *global_mutex and have it as global variable, shared across all threads. But when/how to call g_mutex_new()? I'd like to have it in the constructor of my_class, but the code needs only to be run once. To achieve that, I need locking in the first place, and I face an Chicken-Egg problem.
What you want is a GStaticMutex. Declare it as a static local variable in the thread function, and initialize it with G_STATIC_MUTEX_INIT:
static GStaticMutex my_mutex = G_STATIC_MUTEX_INIT;
This declares, defines and initializes the mutex, so it can be used directly.
See the example in the linked reference.

Does local variable in thread function have separe copy according to thread?

I have declared some local variable in one function like this:
void* thread_function (void* parameter)
{
struct parameter * thread_data = (struct parameter *)parameter;
char buffer[20];
int temp;
}
Here if I have created two threads then in one thread if buffer & temp is updated so will it effect other thread ?
i mean if there are two thread then does there will be two copy of all local variable?
EDIT : then in which case i need to used thread specific data.? i mean pthread_setspecific & all such stuff
These variables are allocated on the stack, and each thread has its own stack: these variables are private to each thread (they are not shared). (See this answer for more details.)
If you assign thread_data to a global pointer, for example, other threads will be able to access thread_data via the global pointer.
Thread specific data (e.g. pthread_setspecific) is used to create variables that are global, but still specific to each thread (not shared): They are thread-specific global variables.
You need to use thread specific variables when you want global variables, but don't want to share them between threads.
It's not that each thread has its own copy, it's that each instance of a function invocation has its own copy of all automatic (i.e. local non-static) variables, regardless of whether the instances are in the same thread or different threads. This is true if the instances come into existence due to invocation in different threads, recursive invocation, mutual/indirect recursion, or even invocation from an asynchronous signal handler. Note that while the C standard does not specify threads, the relevant section in the standard is probably 5.2.3 Signals and interrupts:
Functions shall be implemented such that they may be interrupted at any time by a signal, or may be called by a signal handler, or both, with no alteration to earlier, but still active, invocations' control flow (after the interruption), function return values, or objects with automatic storage duration. All such objects shall be maintained outside the function image (the instructions that compose the executable representation of a function) on a per-invocation basis.
This makes it explicit that each invocation must have its own storage for automatic variables.
Local variables are stored in stack memory, which is private to a thread.
Therefore they are not shared between threads: there will be an independent copy of each variable in each thread
Update
Whether you would want to share data between threads really boils down to a design question; What are your threads doing? Are their effort co-ordinated or are they simply workers processing a queue.
The main thing to consider is synchronization of shared data. Variables that are shared between threads are variables that can change value unexpectedly (within a single thread) and so need to be treated as such. I would suggest that you err on the side of not sharing, unless you have a specific reason to do so.

sharing mutexes between modules

How does one use mutexes between modules?
I have a module that creates threads that run functions from another module.
I need to read a variable in the thread creating module and the threads that execute functions from other #included modules modify the variable. How does locking and unlocking of the mutexes occur in a system like this?
e.g. Logic module spawns 2 threads, each run a function from another module. There is a variable called current position that needs to be read from the logic module if e.g. another module calls getCurrentPosition. How do these threaded functions that are existing outside of the logic module use the mutexes defined in the logic module?
The thread running functions need to lock and unlock the mutex that is defined in the logic module.
You can use mutex just like you declare and use extern variable "current position". No big difference here.
extern pthread_mutex_t mtx;
extern int current_position;
Mutex is is usually used with a pointer to mutex object. So, you must pass the pointer to same object into both modules and then you can use mutex as usual.
You can add extern mutex_type mutex1; declaration of mutex pointer into header file common to both modules but define it in one module with mutex_type mutex1;. Then you can use &mutex1 in both modules.

Resources