Per-thread global variables A simple way to make your library cumbersome to use in a threaded environment, is the use of global variables. They often have to be locked and unlocked, which costs quite a bit of time. If the global variables aren’t neccessarily global in the process but shared between functions (a good example is the infamous errno variable, which is thread-local by the way), the posix specification gives you something useful: pthread_setspecific. With this and some other functions from libpthread you can make an errno-like thread-local global variable. In a modern glibc, errno is no longer an extern int errno; but a macro: #define errno (*__errno_location ()) the __errno_location function finds out the thread-local address where errno is stored. This does not need pthread_getspecific since the C runtime allocates memory for errno explicitely. For our purposes we need to do our own allocation. Of course this is not limited to integers. The only thing we store is a pointer, the C runtime does not care what the pointer points to. So, let’s define our macro first: #define my_var (*(__get_my_var_location())) The __get_my_var_location function now creates the key when it’s first called. It also allocates memory when it is first called in a specific thread: pthread_key_t __my_var_location; That’s easy to use already, but having to type out 2 functions for every variable-like macro which you want to use this way is still a bit cumbersome, so why not let the C preprocessor do it for you? Here’s where it gets evil! You can download the code at the bottom as perthread.h and simply use the following in your code (here’s a full test): #include perthread.h contains the following PER_THREAD macro (you have to imagine a backslash at the endo of each line, wordpress messes it up): #define PER_THREAD(type, name) This macro takes care of creating your initialization function and get_location function, all with the correct type and name. To see that it’s correct, run it through the C preprocessor. |
|
来自: serenayang001 > 《C Program》