Can NIF implementations use the regular C/C++ thread locking primitives or must they use the NIF APIs (enif_mutex_lock(..), enif_mutex_create(..), etc.)
From nif docs
Threads and concurrency
A NIF is thread-safe without any explicit synchronization as long as it acts as a pure function and only reads the supplied arguments. As soon as you write towards a shared state either through static variables or enif_priv_data you need to supply your own explicit synchronization. This includes terms in process independent environments that are shared between threads. Resource objects will also require synchronization if you treat them as mutable.
So there is nothing forbidding you from doing whatever you want. You easily can write your own mutex/semafors and what not. And you can do it in C or C++ or Rust.
That said, there is nothing preventing from braking everything. If you break anything you break it in whole VM. I would try to use standard Erlang ways of doing things, especially while paling with threads. Those are verified methods, and I haven't found any reason for replacing them with anything else.
Related
Interesting that this seems to be a basic question, and yet I couldn't find any example of it for the C language (in SO, I found only for Python, C# and C++).
The point is: as a Qt programmer, when I need to make some data to be transmitted between different threads, I start a signal-slot connection between then and use the emit signal mechanism to do the work.
But now I'm working in a C application for Embedded Linux where I need to do a similar work, but I don't have Qt's mechanism available. The question is: how can I make two or more threads communicate with each other in C in a manner similar to that of Qt with signals and slots?
I know that one of the ways to share data is with global variables with changes protected by mutexes. But even then I would probably be unable to do the system in a asynchronous way: I would have to have a loop that would constantly check if the variable has changed or not. But what if I want to execute a specific method of a thread just after another one finished some work (so, in an asynchronous way)? Then it seems such way fails.
Note: although I'm using Embedded Linux and, therefore, mentioning some options that would take POSIX functions and other "Linux-related ways" would be helpful, it would still be better for the community if more time is given to solutions that are not based strictly to one specific platform (if that is possible).
Read a good tutorial on pthreads. You want to know more about condition variables to be used with mutexes.
Condition variables and mutexes should probably be enough for your needs.
You could also use most traditional inter-process communication mechanisms between threads, e.g. a pipe(7) (probably with poll(2)...). So read Advanced Linux Programming and study syscalls(2) and pthreads(7)
Avoid using signal(7)-s between threads and be aware of signal-safety(7). See however signalfd(2), eventfd(2), userfaultfd(2) (you might cleverly handle SIGSEGV with it) and take inspiration from the approach suggested by Calling Qt functions from Unix signal handler.
Observe a running multi-threaded Linux process with strace(1), ltrace(1), gdb(1). You'll understand that several pthreads(7) primitives are using futex(7).
Both GNU glibc and musl-libc are open source and implement the pthreads specification (and Glib, GTK, Qt or POCO are built above them). I invite you to study their source code.
One way is to use message passing between threads via asynchronous queues. This way you can avoid using shared data between threads and only the queues need to be thread-safe.
Asynchronous queues can be implemented using different synchronisation primitives:
Pipes or sockets.
Queues protected with a mutex and a condition variable.
Non-blocking or lock-free queues.
Thread which you want to notify of an event like "data available" can register a callback function which can be trigerred by the notifier thread. You can use a function pointer for this.
Ex: Thread 2 registers a callback function for one or more events. Thread 1 on occurrence of the condition or event calls the registered function.
producer and consumer threads should capture each other's tid. producer on producing can send:
pthread_kill(consumerID, SIGUSR1);
consumer is setup with the signal handler for SIGUSR1, and can retrieve the produced result from the common std::queue saved by pthread_setspecific().
producer and consumer can continue their tasks without being locked by semaphore or cond var/mutex.
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.
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.
If I have two threads and one global variable (one thread constantly loops to read the variable; the other constantly loops to write to it) would anything happen that shouldn't? (ex: exceptions, errors). If it, does what is a way to prevent this. I was reading about mutex locks and that they allow exclusive access to a variable to one thread. Does this mean that only that thread can read and write to it and no other?
Would anything happen that shouldn't?
It depends in part on the type of the variables. If the variable is, say, a string (long array of characters), then if the writer and the reader access it at the same time, it is completely undefined what the reader will see.
This is why mutexes and other coordinating mechanisms are provided by pthreads.
Does this mean that only that thread can read and write to it and no other?
Mutexes ensure that at most one thread that is using the mutex can have permission to proceed. All other threads using the same mutex will be held up until the first thread releases the mutex. Therefore, if the code is written properly, at any time, only one thread will be able to access the variable. If the code is not written properly, then:
one thread might access the variable without checking that it has permission to do so
one thread might acquire the mutex and never release it
one thread might destroy the mutex without notifying the other
None of these is desirable behaviour, but the mere existence of a mutex does not prevent any of these happening.
Nevertheless, your code could reasonably use a mutex carefully and then the access to the global variable would be properly controlled. While it has permission via the mutex, either thread could modify the variable, or just read the variable. Either will be safe from interference by the other thread.
Does this mean that only that thread can read and write to it and no other?
It means that only one thread can read or write to the global variable at a time.
The two threads will not race amongst themselves to access the global variable neither will they access it at the same time at any given point of time.
In short the access to the global variable is Synchronized.
First; In C/C++ unsynchronized read/write of variable does not generate any exceptions or system error, BUT it can generate application level errors -- mostly because you are unlikely to fully understand how the memory is accessed, and whether it is atomic unless you look at the generated assembler. A multi core CPU may likely create hard-to-debug race conditions when you access shared memory without synchronization.
Hence
Second; You should always use synchronization -- such as mutex locks -- when dealing with shared memory. A mutex lock is cheap; so it will not really impact performance if done right. Rule of thumb; keep the lcok for as short as possible, such as just for the duration of reading/incrementing/writing the shared memory.
However, from your description, it sounds like that one of your threads is doing nothing BUT waiting for the shared meory to change state before doing something -- that is a bad multi-threaded design which cost unnecessary CPU burn, so
Third; Look at using semaphores (sem_create/wait/post) for synchronization between your threads if you are trying to send a "message" from one thread to the other
As others already said, when communicating between threads through "normal" objects you have to take care of race conditions. Besides mutexes and other lock structures that are relatively heavy weight, the new C standard (C11) provides atomic types and operations that are guaranteed to be race-free. Most modern processors provide instructions for such types and many modern compilers (in particular gcc on linux) already provide their proper interfaces for such operations.
If the threads truly are only one producer and only one consumer, then (barring compiler bugs) then
1) marking the variable as volatile, and
2) making sure that it is correctly aligned, so as to avoid interleaved fetches and stores
will allow you to do this without locking.
When trying to implement an asynchronous API calls / Non-blocking calls, I know a little in a All Plain-C application I have, I read a about APM (Asynchronous Programming Model) by 'Delegates'. Basically what I want to do is call one API f1() to do a functionality(which takes long time 8-10 seconds), So I call that API f1(), forget about it, and continue doing some other work, e.g. I/O for to fetch data for next call of the f1() or some functionality not dependent on result of f1().
If any one has used that APM model of programming, I am looking at some concise explanation for implementing non-blocking calls.
Is there any other way of implementing asynchronous APIs , any other library/framework which might help in this?
You basically need to create a multi-threaded (or multi-process) application. The f1() API needs to spawn a thread (or process) to process the data in a separate execution space. When it completes, the f1() routine needs to signal the main process that the execution is done (signal(), message queues, etc).
A popular way to do asynchronous programming in a plain C programs is to use an "event loop". There are numerous libraries that you could use. I suggest to take a look at
glib.
Another alternative is to use multiple pre-emptive threads (one for each concurrent operation) and synchronize them with mutexes and condition variables. However, pre-emptive threading in plain C is something I would avoid, especially if you want to write portable programs. It's hard to know which library functions are re-entrant, signal handling in threaded programs is a hassle, and in general C libraries and system functions have been designed for single-threaded use.
If you're planning to run your application only on one platform (like Windows) and the work done with f1() is a relatively simple thing, then threading can be OK.
If the function f1() which you are referring to is not itself implemented in a asynchronous fashion, you will need to wrap it up in its own thread yourself. When doing this, you need to be careful with regards to side effects that may be caused by that particular function being called. Many libraries are not designed in a thread-safe way and multiple concurrent invocations of functions from such libraries will lead to data corruption. In such cases, you may need to wrap up the functionality in an external worker process. For heavy lifting that you mention (8-10 seconds) that overhead may be acceptable. If you will only use the external non-threadsafe functions in one thread at a time, you may be safe.
The problem with using any form of event-loop is that an external function which isn't aware of your loop will never yield control back to your loop. Thus, you will not get to do anything else.
Replace delegates with pointers to functions in C, everything else is basically same to what you have read.
Well. Basically I've seen 2 types of async API:
Interrupt. You give a call a callback which should be performed after the call. GIO (part of previously mentioned GLib) works in such a way. It is relatively easy to program with but you usually have the thread in which the callback will be run changed (except if it is integrated with the main loop as in the case of GIO).
Poll. You check if the data is available. The well-known BSD Sockets operate in such a manner. It has an advantage of not necessarily being integrated with the main loop and running callback in a specific thread.
If you program for Gnome or Gtk+-based I'd like to add that GTask seems to be a very nice (potentially nice? I haven't used it). Vala will have better support for GIO-like async calls.