Is there a mechanism for a library supplying a thread local variable to register a constructor function for it?
I'd like to have my library supply a thread-local struct which should be initialized on thread creation with dynamically obtained data.
If the struct was just global but not thread-local, I'd have a function marked with gcc's __attribute__((__constructor__)) initialize it, but these constructors don't retrigger when a new thread is created.
No, thread creation does not invoke any constructors. This is a good thing; automatic invocation of constructors would not scale in a potentially large application where most threads have nothing to do with your library code and will never call it.
Instead, you need to either have your library code that uses the thread-local object construct it lazily on the first library call in the new thread, or require the calling application to call an initialization function explicitly in threads that will use it. The first option is generally a lot better and the performance impact should not even be measurable; accessing thread-local storage in a library takes longer than a predictable branch:
static _Thread_local int init_done;
if (!init_done) ...
Related
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.
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.
I am writing a shared library in C. I know C functions are not thread safe.
My library routines looks like,
struct lib_handle {
....
};
int lib_init(lib_handle **handle);
int lib_process(lib_handle *handle);
....
....
Every method takes a pointer to lib_handle object. All the state is stored inside this structure. No global variables are used.
I assume if each thread creates it's own lib_handle instances, multiple threads can use the library functions. Since each thread has it's own handle, everythibg should work.
I haven't validated this assumption yet. I am wondering what you guys think about this design and do you thing I can state my library as thread safe given each thread has it's own handles?
Any help would be great!
That will make data/state of library thread safe.
But you also have to make sure that your library uses threadsafe functions from other libraries, e.g. use strtok_r instead of strtok.
Threads works in shared memory space. Unsafe objects are the objects which can be accessed by multiple threads simulteniously. So if you have single lib_handle object for each threads there will be no problems.
If each thread has a private lib_handle object your library should be fully threadsafe; if you let several threads share lib_handle objects the person using your library can still makea thread safe program if she uses your library correctly (i.e. your library is not inherently thread-unsafe which it would be if you used e.g. global variables).
If this mode of operation (shared lib_handle) is interesting you should clearly separate the functions which only read the state of lib_handle and those which manipulate the state of lib_handle. The former needing a read lock and the latter needing a write lock (the calling scope must handle this).
For what it is worth I have used the pattern you describe quite a lot, and like it.
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.
Say a program spawns a thread. That thread calls func1(). However, func1() is also called in various places elsewhere in the main app. If i wrap it in a mutex lock in the thread only, will it be safe for the whole of the app? Or will one have to go in it and lock it? And if in it are other functions that are called by it but also on the main app in various places, does one have to go recursively and lock them?
Get out of the habit of thinking that you protect functions with mutexes, you don't.
You actually protect resources such as variables shared amongst threads.
Once you accept that little pearl of wisdom, you start thinking in terms of what data has to be protected and can minimise the granularity of the protections.
For example, if func1() and func2() both access the shared variable x, and you can call func2() either from func1() or main(), you're going to have to engineer a solution that can detect if the mutex is already locked so that func2() can claim/release (when called from main) or do nothing (when called from func1()). Either that or use a recursive mutex.
Functions which are thread-unsafe (such as using static data areas) can be protected with mutexes but I find it's usually easier to refactor them so that they're inherently thread-safe (with allocated memory or thread-local storage).
You only need to lock shared resources, or anything not thread-local. You should also consider writing your functions to be reentrant whenever possible. Reentrant functions are inherently thread-safe, whereas not all thread-safe functions can be made reentrant.
As long as you declare static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; in the function and use it, you can accomplish what you want. But making functions which are not reentrant, which have global state, etc. is generally a Bad Thing(tm). Good design is to lock data, and not to have globals (or singletons which is a euphemism for global variables).