In C++ it's recommended to use lock_guard as it ensures when the object is destroyed it unlocks the mutex.
Is there a way to implement the same thing in C? Or do we have to just implement it manually:
lock mutex
Do something on a global variable
unlock mutex
#include <stdio.h>
#include <threads.h>
long long x = 0;
mtx_t m;
static void do1() {
mtx_lock(&m);
for(int i = 0; i < 100; i++){
x = x +1;
}
mtx_unlock(&m);
}
static void do2() {
mtx_lock(&m);
x = x / 3;
mtx_unlock(&m);
}
int main(int argc, char *argv[])
{
mtx_init(&m, mtx_plain);
thrd_t thr1;
thrd_t thr2;
thrd_create(&thr1, do1, 0);
thrd_create(&thr2, do2, 0);
thrd_join(&thr2, 0);
thrd_join(&thr1, 0);
return 0;
}
std::lock_guard
is an example of a general C++ concept known as RAII. C++ programmers need this because a C++ function may be exited in ways the programmer didn't write themselves, via an exception being thrown.
C does not have exceptions, so a concept like RAII, despite its merits and utility, isn't really needed. To accomplish this sort of paired action in C you'll need to call the two functions yourself. How you do it exactly is entirely up to you. For instance, you can defer the locking to a wrapper function that accepts a callback:
static inline void do_locked( void (*cb)(void) ) {
mtx_lock(&m);
cb();
mtx_unlock(&m);
}
static inline void do2_impl(void) {
x = x / 3;
}
static void do2() {
do_locked(do2_impl);
}
Discipline to keep your code well structured is all it takes really, even if you don't have the same toolbox C++ gives you.