Is it possible for 2 threads lock a mutex at the same time (use mutex wrapper)?











up vote
-2
down vote

favorite












The question comes from an exmaple of std::condition_variable



As far as I know, when I construct a new thread, it starts to execute immediately.



So I wonder, would cv.wait(lk, {return ready;}); in worker_thread(), and std::lock_guard<std::mutex> lk(m); in main, lock the mutex at the same time? Could this happen?



(From cppreference I know that std::condition_variable::wait and std::lock_guard would lock the mutex during the construction.)



#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex m;
std::condition_variable cv;
std::string data;
bool ready = false;
bool processed = false;

void worker_thread()
{
// Wait until main() sends data
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, {return ready;});

// after the wait, we own the lock.
std::cout << "Worker thread is processing datan";
data += " after processing";

// Send data back to main()
processed = true;
std::cout << "Worker thread signals data processing completedn";

// Manual unlocking is done before notifying, to avoid waking up
// the waiting thread only to block again (see notify_one for details)
lk.unlock();
cv.notify_one();
}

int main()
{
std::thread worker(worker_thread);

data = "Example data";
// send data to the worker thread
{
std::lock_guard<std::mutex> lk(m);
ready = true;
std::cout << "main() signals data ready for processingn";
}
cv.notify_one();

// wait for the worker
{
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, {return processed;});
}
std::cout << "Back in main(), data = " << data << 'n';

worker.join();
}









share|improve this question




















  • 1




    std::condition_variable::wait 1) __Atomically releases lock__, blocks the current executing thread, and adds it to the list of threads waiting on *this. The thread will be unblocked when notify_all() or notify_one() is executed. It may also be unblocked spuriously. When unblocked, regardless of the reason, lock is reacquired and wait exits. If this function exits via exception, lock is also reacquired.
    – tkausl
    Nov 11 at 7:04

















up vote
-2
down vote

favorite












The question comes from an exmaple of std::condition_variable



As far as I know, when I construct a new thread, it starts to execute immediately.



So I wonder, would cv.wait(lk, {return ready;}); in worker_thread(), and std::lock_guard<std::mutex> lk(m); in main, lock the mutex at the same time? Could this happen?



(From cppreference I know that std::condition_variable::wait and std::lock_guard would lock the mutex during the construction.)



#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex m;
std::condition_variable cv;
std::string data;
bool ready = false;
bool processed = false;

void worker_thread()
{
// Wait until main() sends data
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, {return ready;});

// after the wait, we own the lock.
std::cout << "Worker thread is processing datan";
data += " after processing";

// Send data back to main()
processed = true;
std::cout << "Worker thread signals data processing completedn";

// Manual unlocking is done before notifying, to avoid waking up
// the waiting thread only to block again (see notify_one for details)
lk.unlock();
cv.notify_one();
}

int main()
{
std::thread worker(worker_thread);

data = "Example data";
// send data to the worker thread
{
std::lock_guard<std::mutex> lk(m);
ready = true;
std::cout << "main() signals data ready for processingn";
}
cv.notify_one();

// wait for the worker
{
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, {return processed;});
}
std::cout << "Back in main(), data = " << data << 'n';

worker.join();
}









share|improve this question




















  • 1




    std::condition_variable::wait 1) __Atomically releases lock__, blocks the current executing thread, and adds it to the list of threads waiting on *this. The thread will be unblocked when notify_all() or notify_one() is executed. It may also be unblocked spuriously. When unblocked, regardless of the reason, lock is reacquired and wait exits. If this function exits via exception, lock is also reacquired.
    – tkausl
    Nov 11 at 7:04















up vote
-2
down vote

favorite









up vote
-2
down vote

favorite











The question comes from an exmaple of std::condition_variable



As far as I know, when I construct a new thread, it starts to execute immediately.



So I wonder, would cv.wait(lk, {return ready;}); in worker_thread(), and std::lock_guard<std::mutex> lk(m); in main, lock the mutex at the same time? Could this happen?



(From cppreference I know that std::condition_variable::wait and std::lock_guard would lock the mutex during the construction.)



#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex m;
std::condition_variable cv;
std::string data;
bool ready = false;
bool processed = false;

void worker_thread()
{
// Wait until main() sends data
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, {return ready;});

// after the wait, we own the lock.
std::cout << "Worker thread is processing datan";
data += " after processing";

// Send data back to main()
processed = true;
std::cout << "Worker thread signals data processing completedn";

// Manual unlocking is done before notifying, to avoid waking up
// the waiting thread only to block again (see notify_one for details)
lk.unlock();
cv.notify_one();
}

int main()
{
std::thread worker(worker_thread);

data = "Example data";
// send data to the worker thread
{
std::lock_guard<std::mutex> lk(m);
ready = true;
std::cout << "main() signals data ready for processingn";
}
cv.notify_one();

// wait for the worker
{
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, {return processed;});
}
std::cout << "Back in main(), data = " << data << 'n';

worker.join();
}









share|improve this question















The question comes from an exmaple of std::condition_variable



As far as I know, when I construct a new thread, it starts to execute immediately.



So I wonder, would cv.wait(lk, {return ready;}); in worker_thread(), and std::lock_guard<std::mutex> lk(m); in main, lock the mutex at the same time? Could this happen?



(From cppreference I know that std::condition_variable::wait and std::lock_guard would lock the mutex during the construction.)



#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex m;
std::condition_variable cv;
std::string data;
bool ready = false;
bool processed = false;

void worker_thread()
{
// Wait until main() sends data
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, {return ready;});

// after the wait, we own the lock.
std::cout << "Worker thread is processing datan";
data += " after processing";

// Send data back to main()
processed = true;
std::cout << "Worker thread signals data processing completedn";

// Manual unlocking is done before notifying, to avoid waking up
// the waiting thread only to block again (see notify_one for details)
lk.unlock();
cv.notify_one();
}

int main()
{
std::thread worker(worker_thread);

data = "Example data";
// send data to the worker thread
{
std::lock_guard<std::mutex> lk(m);
ready = true;
std::cout << "main() signals data ready for processingn";
}
cv.notify_one();

// wait for the worker
{
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, {return processed;});
}
std::cout << "Back in main(), data = " << data << 'n';

worker.join();
}






c++






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 11 at 7:04

























asked Nov 11 at 7:01









Rick

1,535929




1,535929








  • 1




    std::condition_variable::wait 1) __Atomically releases lock__, blocks the current executing thread, and adds it to the list of threads waiting on *this. The thread will be unblocked when notify_all() or notify_one() is executed. It may also be unblocked spuriously. When unblocked, regardless of the reason, lock is reacquired and wait exits. If this function exits via exception, lock is also reacquired.
    – tkausl
    Nov 11 at 7:04
















  • 1




    std::condition_variable::wait 1) __Atomically releases lock__, blocks the current executing thread, and adds it to the list of threads waiting on *this. The thread will be unblocked when notify_all() or notify_one() is executed. It may also be unblocked spuriously. When unblocked, regardless of the reason, lock is reacquired and wait exits. If this function exits via exception, lock is also reacquired.
    – tkausl
    Nov 11 at 7:04










1




1




std::condition_variable::wait 1) __Atomically releases lock__, blocks the current executing thread, and adds it to the list of threads waiting on *this. The thread will be unblocked when notify_all() or notify_one() is executed. It may also be unblocked spuriously. When unblocked, regardless of the reason, lock is reacquired and wait exits. If this function exits via exception, lock is also reacquired.
– tkausl
Nov 11 at 7:04






std::condition_variable::wait 1) __Atomically releases lock__, blocks the current executing thread, and adds it to the list of threads waiting on *this. The thread will be unblocked when notify_all() or notify_one() is executed. It may also be unblocked spuriously. When unblocked, regardless of the reason, lock is reacquired and wait exits. If this function exits via exception, lock is also reacquired.
– tkausl
Nov 11 at 7:04














2 Answers
2






active

oldest

votes

















up vote
3
down vote



accepted










Mutex are meant to get a lock on resource, only 1 thread can get that lock. Locking of mutex is atomic, 2 threads cannot acquire a lock on mutex, if they can, then it defeats the purpose of mutex locks!




Mutexes are built such that locking is an atomic operation: it will only complete on one thread at a time, regardless of how many threads are attempting to lock







share|improve this answer






























    up vote
    1
    down vote













    "Mutex" is a contraction of "mutual exclusion"; it's purpose is to allow only one thread to lock the mutex at any time.



    That said, there's a serious problem in that example. It has a potential deadlock, because it tries too hard to sequence inherently non-sequential operations.



    The problem occurs if main goes through its locking code, sets ready to true, and calls notify() before the new thread locks the mutex and calls wait(). If that happens, main will proceed to its call to wait() while the new thread is sitting in wait(), and neither one will notify the other one; they're both waiting for the other one to do something.



    If you're unlucky, you won't see this when you're testing the code; it might happen that the new thread starts to wait() before the main thread calls notify(), and then the code will work as expected. That's unlucky because sooner or later it will lock up, most likely when you're demonstrating your code to your most important customer.






    share|improve this answer





















    • Wow, thankyou, you are right, I haven't noticed that. Maybe you should remind cppreference about this example.
      – Rick
      Nov 12 at 9:19













    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53246550%2fis-it-possible-for-2-threads-lock-a-mutex-at-the-same-time-use-mutex-wrapper%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    3
    down vote



    accepted










    Mutex are meant to get a lock on resource, only 1 thread can get that lock. Locking of mutex is atomic, 2 threads cannot acquire a lock on mutex, if they can, then it defeats the purpose of mutex locks!




    Mutexes are built such that locking is an atomic operation: it will only complete on one thread at a time, regardless of how many threads are attempting to lock







    share|improve this answer



























      up vote
      3
      down vote



      accepted










      Mutex are meant to get a lock on resource, only 1 thread can get that lock. Locking of mutex is atomic, 2 threads cannot acquire a lock on mutex, if they can, then it defeats the purpose of mutex locks!




      Mutexes are built such that locking is an atomic operation: it will only complete on one thread at a time, regardless of how many threads are attempting to lock







      share|improve this answer

























        up vote
        3
        down vote



        accepted







        up vote
        3
        down vote



        accepted






        Mutex are meant to get a lock on resource, only 1 thread can get that lock. Locking of mutex is atomic, 2 threads cannot acquire a lock on mutex, if they can, then it defeats the purpose of mutex locks!




        Mutexes are built such that locking is an atomic operation: it will only complete on one thread at a time, regardless of how many threads are attempting to lock







        share|improve this answer














        Mutex are meant to get a lock on resource, only 1 thread can get that lock. Locking of mutex is atomic, 2 threads cannot acquire a lock on mutex, if they can, then it defeats the purpose of mutex locks!




        Mutexes are built such that locking is an atomic operation: it will only complete on one thread at a time, regardless of how many threads are attempting to lock








        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 11 at 7:21









        user4581301

        19.1k51830




        19.1k51830










        answered Nov 11 at 7:06









        Abhijith Shivaswamy

        3115




        3115
























            up vote
            1
            down vote













            "Mutex" is a contraction of "mutual exclusion"; it's purpose is to allow only one thread to lock the mutex at any time.



            That said, there's a serious problem in that example. It has a potential deadlock, because it tries too hard to sequence inherently non-sequential operations.



            The problem occurs if main goes through its locking code, sets ready to true, and calls notify() before the new thread locks the mutex and calls wait(). If that happens, main will proceed to its call to wait() while the new thread is sitting in wait(), and neither one will notify the other one; they're both waiting for the other one to do something.



            If you're unlucky, you won't see this when you're testing the code; it might happen that the new thread starts to wait() before the main thread calls notify(), and then the code will work as expected. That's unlucky because sooner or later it will lock up, most likely when you're demonstrating your code to your most important customer.






            share|improve this answer





















            • Wow, thankyou, you are right, I haven't noticed that. Maybe you should remind cppreference about this example.
              – Rick
              Nov 12 at 9:19

















            up vote
            1
            down vote













            "Mutex" is a contraction of "mutual exclusion"; it's purpose is to allow only one thread to lock the mutex at any time.



            That said, there's a serious problem in that example. It has a potential deadlock, because it tries too hard to sequence inherently non-sequential operations.



            The problem occurs if main goes through its locking code, sets ready to true, and calls notify() before the new thread locks the mutex and calls wait(). If that happens, main will proceed to its call to wait() while the new thread is sitting in wait(), and neither one will notify the other one; they're both waiting for the other one to do something.



            If you're unlucky, you won't see this when you're testing the code; it might happen that the new thread starts to wait() before the main thread calls notify(), and then the code will work as expected. That's unlucky because sooner or later it will lock up, most likely when you're demonstrating your code to your most important customer.






            share|improve this answer





















            • Wow, thankyou, you are right, I haven't noticed that. Maybe you should remind cppreference about this example.
              – Rick
              Nov 12 at 9:19















            up vote
            1
            down vote










            up vote
            1
            down vote









            "Mutex" is a contraction of "mutual exclusion"; it's purpose is to allow only one thread to lock the mutex at any time.



            That said, there's a serious problem in that example. It has a potential deadlock, because it tries too hard to sequence inherently non-sequential operations.



            The problem occurs if main goes through its locking code, sets ready to true, and calls notify() before the new thread locks the mutex and calls wait(). If that happens, main will proceed to its call to wait() while the new thread is sitting in wait(), and neither one will notify the other one; they're both waiting for the other one to do something.



            If you're unlucky, you won't see this when you're testing the code; it might happen that the new thread starts to wait() before the main thread calls notify(), and then the code will work as expected. That's unlucky because sooner or later it will lock up, most likely when you're demonstrating your code to your most important customer.






            share|improve this answer












            "Mutex" is a contraction of "mutual exclusion"; it's purpose is to allow only one thread to lock the mutex at any time.



            That said, there's a serious problem in that example. It has a potential deadlock, because it tries too hard to sequence inherently non-sequential operations.



            The problem occurs if main goes through its locking code, sets ready to true, and calls notify() before the new thread locks the mutex and calls wait(). If that happens, main will proceed to its call to wait() while the new thread is sitting in wait(), and neither one will notify the other one; they're both waiting for the other one to do something.



            If you're unlucky, you won't see this when you're testing the code; it might happen that the new thread starts to wait() before the main thread calls notify(), and then the code will work as expected. That's unlucky because sooner or later it will lock up, most likely when you're demonstrating your code to your most important customer.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 11 at 17:05









            Pete Becker

            56.3k439115




            56.3k439115












            • Wow, thankyou, you are right, I haven't noticed that. Maybe you should remind cppreference about this example.
              – Rick
              Nov 12 at 9:19




















            • Wow, thankyou, you are right, I haven't noticed that. Maybe you should remind cppreference about this example.
              – Rick
              Nov 12 at 9:19


















            Wow, thankyou, you are right, I haven't noticed that. Maybe you should remind cppreference about this example.
            – Rick
            Nov 12 at 9:19






            Wow, thankyou, you are right, I haven't noticed that. Maybe you should remind cppreference about this example.
            – Rick
            Nov 12 at 9:19




















             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53246550%2fis-it-possible-for-2-threads-lock-a-mutex-at-the-same-time-use-mutex-wrapper%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Bressuire

            Vorschmack

            Quarantine