Wyjście z funkcji bez odpalenia LeaveCriticalSection

0
LRESULT DoSomething()
{
    EnterCriticalSection(&cs);

    if (...)
        return 1;

    LeaveCriticalSection(&cs);

    return 0;
}

Wydaje mi się, że nie wolno wyjść z funkcji przed wywołaniem LeaveCriticalSection(). Czy mam rację? Co może spowodować powyższy kod, gdy warunek w if-ie będzie spełniony? Dodam, że tego typu numer widzę w dość rozbudowanych aplikacjach pisanych przez osoby, które jak mniemam - znają się na tym co tworzą. Ale odnoszę wrażenie iż w tym wypadku z pośpiechu coś przeoczyli.

0

W tym przypadku może dojść do deadlocka, jeżeli funkcja wywołująca nie zwalnia cs. Proponuję poczytać o RAII i wykorzystać ten mechanizm.

0

Ok, więc mogę po prostu stworzyć klasę wykorzystującą te dwie funkcje i w destruktorze wywołać:

LeaveCriticalSection(&cs)

by rozwiązać ten problem.

Ale zastanawia mnie jeszcze coś. Sekcje krytyczne często wykorzystuje się podczas operowania na obiekcie vector. Powinny być wykorzystywane tylko podczas dodawania, modyfikowania lub usuwania elementów wektora tak? Nie ma tu znaczenia ile wątków naraz będzie odczytywać jego elementy?

0

Tak. Ale jeśli inny wątek dodaje/usuwa/modyfikuje to musisz synchronizować czytanie.

0

Wydaje mi się, że nie wolno wyjść z funkcji przed wywołaniem LeaveCriticalSection().

Wyjść teoretycznie wolno, ale trzeba dopilnować żeby LeaveCriticalSection się jednak gdzieś wykonało. Czy przed, czy po wyjściu z funkcji, to dla systemu wszystko jedno.
Ale lepiej dopilnować żeby Leave było w tej samej funkcji co Enter, bo inaczej szybko stracimy panowanie nad kodem.

LRESULT DoSomething()
{
    EnterCriticalSection(&cs);
    if (...)
    {
        LeaveCriticalSection(&cs);
        return 1;
    }
    LeaveCriticalSection(&cs);
    return 0;
}
0

Albo tak:

LRESULT DoSomething()
{
    LRESULT res=S_OK;

    EnterCriticalSection(&cs);

    if (...)
    {
        blah;
        res = E_FAIL;
    }

    if ( S_OK == res && ...)
    {
        blah;
        res = E_FAIL;
    }

    LeaveCriticalSection(&cs);
    return res;
}
2
#include <iostream>
using namespace std;

#include <windows.h>

class Krytyk
{
public:
    Krytyk()
    {
        InitializeCriticalSection(&cs);
    }
    ~Krytyk()
    {
        DeleteCriticalSection(&cs);
    }
    template<typename F>
    void operator()(F func)
    {
        EnterCriticalSection(&cs);
        func();
        LeaveCriticalSection(&cs);
    }
    template<typename F, typename R>
    void operator()(R &retval, F func)
    {
        EnterCriticalSection(&cs);
        retval = func();
        LeaveCriticalSection(&cs);
    }
private:
    CRITICAL_SECTION cs;
};

int main()
{
    Krytyk critical;
    int ret;

    critical([&ret]()
    {
        ret = 4;
    });
    cout << ret << endl;

    critical(ret, []()
    {
        return 3;
    });
    cout << ret << endl;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1