简体   繁体   中英

Mutex doesn't work

My code is an AVL tree and am trying to enter with mutex .

The mutex does not work. Why?

Return black screen, perhaps a deadlock. I don't know. Not exist recursive functions.

If I use a lock guard it works normally.

template<typename T> int avl<T>::insere (int key , T data) {

    mtx.lock();

    no * nw = new no;

    if (nw == NULL)
        return 0;

    nw->sire = NULL;
    nw->left = NULL;
    nw->right = NULL;
    nw->key = key;
    nw->data = data;

      if (tree.root == NULL) {
        tree.root = nw;
        tree.quant++;
        return 1;
    }
    no * son = tree.raiz;
    no * sire  = NULL;

    while (son != NULL) {

        sire = son;

        if (key < son->key)
            son = son->left;

        else
            son = son->right.;

    }
    nw->sire = sire;

    if (key < sire->key)
        sire->left = nw;

    else
        sire->right = nw;

    tree.quantidade++;

    no * current = nw;

    while (current != NULL) {

        int f = fator (nw);

        if (f >= 2 || f <= 2)
            balance( current);
        current = current->sire;
    }

    mtx.unlock();

    return 1;
}

A std::lock_guard uses a concept which is called RAII (Resource acquisition is initialization)

RAII in short: you do an action in the constructor and do the "undo" operation in the destructor. For a Mutex this would be unlock

So with the lock_guard whenever you return (go out of scope) the mutex will be automatically unlocked.

When you change it to a "manual" mutex you have to make sure that you do the unlock on each possible exit of the function (before each return ).

This is the reason why the RAII classes exist. So you don't have to worry about this. Whenever you change the function and add another return you can forget to add the unlock . With a lock_guard you don't have to think about it.

There are alternatives to this. Several SCOPE_EXIT makros which execute a statement the moment it leaves the scope (see BOOST or my more favorite folly/ScopeGuard for more info about this). Though they are more usefull if you don't already have a RAII class (like lock_guard ).

There are several other examples for this in modern c++ ( shared_ptr and unique_ptr for example). In general you should prefer the RAII implementations over the manual approach to have a more robust code and less error prone.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM