Есть что-то, что напоминает std::lock_guard в родном C?

В C++ рекомендуется использовать lock_guard, поскольку он гарантирует, что когда объект уничтожен, он разблокирует мьютекс.

Есть ли способ реализовать то же самое в C? Или мы должны просто реализовать это вручную:

блокировка мьютекса

Сделайте что-нибудь с глобальной переменной

разблокировать мьютекс

#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;
}

1 ответ

Решение

std::lock_guard является примером общей концепции C++, известной как RAII. Программисты C++ нуждаются в этом, потому что функция C++ может быть закрыта способами, которые программист не написал сам, через исключение.

C не имеет исключений, поэтому такая концепция, как RAII, несмотря на ее достоинства и полезность, на самом деле не нужна. Чтобы выполнить такое парное действие в C, вам нужно вызвать обе функции самостоятельно. Как именно вы это делаете, полностью зависит от вас. Например, вы можете отложить блокировку до функции-оболочки, которая принимает обратный вызов:

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);
}

Дисциплина для поддержания вашего кода хорошо структурированной - это все, что нужно на самом деле, даже если у вас нет того же инструментария, который дает вам C++.

Другие вопросы по тегам