A function in a pthread - c

Can I call another function in a thread runner function, called by a pthread_create()? Are there any restrictions on such functions?

Yes, you can (and doing so is fairly frequent). The main restriction is that you need to synchronize threads when two or more access the same data (at least if there's any chance that any of them might modify that data).

You can call any function from a runner function. BUT, you should make sure that any function in a multi-threaded system is protected with mutexes correctly.

You can call any function you want from a thread, but C does not automatically synchronize values. If a function uses global variables or static variables then you may get some bad surprises when you call it in multi-threaded code.

Related

How to determine that multiple threads call function simultaneously in C?

I want to determine whether certain function in C can be called from multiple threads at the same time, in order to understand if I need to protect it with mutexes. The file where the function is implemented and defined does not have any mutex mechanism, so there is a chance that only one thread ever accesses the function but there is a chance that multiple threads do.
I thought to add a thread local storage variable which I increment upon starting the function and decrement upon exiting the function. If, after decrementing, the value of the variable is greater than 0, then multiple threads access the function.
This is my code:
#include <stdio.h>
static __thread int threadCounter = 0;
void f(void)
{
threadCounter++;
// do something
threadCounter--;
printf("threadCounter: %d\n", threadCounter);
}
a'm wondering if this solution is sufficient to determine whether multiple threads access a function and whether there are better ways to accomplish this.
From the GCC documentation :
"Thread-local storage (TLS) is a mechanism by which variables are allocated such that there is one instance of the variable per extant thread."
Thus, your solution will always indicate that only one thread access your function at the time even if it's not the case. You should use a variable that is shared between thread. But using a volatile one is still not a good solution because if there are multiple thread accessing it at the time, the value might not be the good one.
In conclusion, I think the better way of doing this would be to setup a mutex and using the pthread_mutex_trylock function to detect if there are multiple threads trying to call your function.
A thread local variable is by definition only visible for the current thread, your solution won't work. But your approach is good. Instead of using a thread local variable you should use a variable protected by a mutex.
This test either is using a local variable, or it isn't thread-safe in itself. In either case, it won't be useful as proof. If you want to use a counter, you have to protect it with something like a mutex or critical section. There's pretty much no way around this.
But there's a another way to do this better though, giving you exact information of who called the function, while at the same time not having to modify the actual function. You can create a "mock" function:
#define f() ( print(__func__), f() )
This prints the name of the thread callback function, then calls the actual function f(). This works because the pre-processor token f() is evaluated before any function call.
I wrote the function as a custom one print, since you'll still have the problem with multiple thread trying to access stdout at once if you use printf etc. So the custom print function must contain the means of thread-safety.

Call functions that require the main thread from different fibers

There are lots of functions that are supposed to be called from the main thread. In my limited experience, these are mostly UI functions.
Examples:
-[UIApplication delegate] must be called from main thread only)
java.lang.IllegalStateException: Not on the main thread
Drawing to window from child thread
Suppose I have a fiber library that creates "threads" with set/get context. Is it safe to call main thread only functions from any fiber started from the main OS thread?
I think it is fine since the OS doesn't know about my fibers, but I'm not sure. I would test this, but the results would not be definitively since it might work but be relying on undefined behavior.
Edit: marking this question C since set/get context are C functions, although as mentioned in the comments I think it may apply to programs written in other languages as well.
Yes, you can call any function in your program from any context. Note that using getcontext and setcontext are not making real "threads", and you're not getting any parallel processing with this - you're only getting scheduling. That's why it will work, no matter if it's a UI function or not. It's basically just a goto that works cross-function. To quote the manpage directly:
If the context was obtained by a call of getcontext(), program
execution continues as if this call just returned.
That means if I write
... code ...
getcontext(&cxt);
... code ...
setcontext(&cxt);
Then when I reach setcontext, the state that I go to is identical to when the function getcontext just returned. There is no perceivable difference (Of course, you may have changed memory values in the mean time, but that's beside the point). The manpage has a similar guarantee with makecontext, but with the note that it'll redirect you after the given function finishes execution.
The examples you give are in higher level programming langauges, which have a lot more complexity, and thus are not as simple as setcontext/getcontext in C. The Java Error you posted seems to actually be a distinct OS thread, and same with the third example. The first example looks like it might be a fake thread but of course there are hidden complexities which might prevent UI calls from working (Since they interact with external APIs).
That's why threading in JS is so easy: because the threads aren't real. What you lose in parallel performance you gain in being able to call anything anywhere from your dispatched functions and ajax calls.
If you know your fiber library is really only using getcontext and setcontext, then you'll be fine. The library might do something else though, so it would be good to verify with the library writers in such a situation.

Can I call function within a thread? C

I want to improve the speed of a certain C application and for that I will be using threads. What concerns me is if I can, within a function being executed in a different thread, call another function of that is not being executed in the same thread: Example:
void checks_if_program_can_do_something()
{
}
void does_something()
{
checks_if_program_can_do_something();
}
int main()
{
does_something(); //another thread is used to execute this function
return 1;
}
In this case, the function does_something() calls the function checks_if_program_can_do_something(), but does_something() is being executed in another thread. I hope I made myself clear. Can I also call the function checks_if_program_can_do_something() in other functions using multiple threads?
Yes, but you should take care that the function does not alter state in such a way that other threads would be impacted negatively.
The terms related to this kind of protection are reentrant, which means the program can safely be paused and continued, and thread-safe which means that two non-pausing calls can be made at the same time.
These features you add to a function require programming approaches that might differ from most people's standard approaches; but, they handle two important scenarios that must be accounted for when writing threaded code:
The CPU pauses part of your program (it needs to wait on I/O) or needs the core for a different part of your program.
The CPU decides to run two threads of your program at the same time on different cores.
Gide lines for safe programming approaches are plentiful, but I've provided one here for you to get started. Keep in mind that if you use someone else's code in a threaded situation, you also need to verify that their code is written to be reentrant / thread safe.

Making a C library thread safe

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.

non-thread safe libraries and threads

Using non-thread safe libraries with threads. Say I have a library that makes a connection to a server. And it is non thread safe. Can I use initiate the library inside 2 threads?
ie:
thread_1(){
telnet_lib_t *connection1;
while(1){
do_somestuff
}
free_telnet(connection1);
}
thread_2(){
telnet_lib_t *connection2;
while(1){
do_somestuff;
}
free_telnet(connection2);
}
Would this work? Now I have 2 independent instances of the library running. So they would not interfere with each other, right?
No, you can't do this. If the library has no global state and its functions are just internally non-thread-safe, you could solve the problem by having the whole library protected by a mutex and only allowing one thread to access it at once (but this might be prohibitive, especially if the library performs any slow or blocking tasks). But if the library fundamentally has a singular global state it uses, and no way to save/restore/swap states, then there's simply no way to use it in multiple threads (or even to use multiple contexts in alternation in a non-threaded program). Such libraries are generally considered trash and should be replaced.
It depends on why it isn't threadsafe.
For example, if the library uses some static variable then that would still be shared between two threads.
So, generally this would be a bad idea. If something isn't threadsafe don't use it in threads, but, you could fork a child process and then use it, which is heavier than threads, but safer.
Without knowing more about the specifics of the non-thread-safe library, it's not possible to say it's safe to use as you suggest.
If the library has any global shared resource (e.g. a global variable), the two threads could well step on each other, overwriting that global variable in a manner not intended by the library writer.
The trouble is, no amount of testing can prove with certainty that you will not eventually trigger a conflict.
If you must use the library in parallel, the only safe way I can think of to do that is to use process isolation... create multiple child processes that each load an instance of the library.
You can do that only if you know that the telnet_lib_t and its methods don't work with any global state (i.e. they are not relying on global variables). If you know that the library's state is contained within itself, for sure then use it, otherwise don't do it. Even if you don't run into any issue during your testing, it won't mean there isn't a problem lurking somewhere.

Resources