1

The code below can never print m4 (and of course no t2 and t3) on VS 2013. It behaves like a deadlock and I don't know the reason. Is there anything I missed?

#include <mutex>
#include <thread>
#include <chrono>

#include <stdio.h>

std::mutex m;

void work()
{
    printf("t1\n");

    m.lock();
    printf("t2\n");

    m.unlock();
    printf("t3\n");

    return;
}

int _tmain(int argc, _TCHAR* argv[])
{
    printf("m1\n");

    m.lock();
    printf("m2\n");

    std::thread *th = new std::thread(work);
    printf("m3\n");

    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    printf("m4\n");

    m.unlock();
    printf("m5\n");

    th->join();
    return 0;
}

Edit: Yes, I cannot see deadlock. But just try it in VS 2013. It locks. I want to know the reason. Is this a VS bug or somthing goes wrong?

The program runs with the follow output:

m1
m2
t1
m3

It blocks at std::this_thread::sleep_for(std::chrono::milliseconds(1000)); forever, but why?

guan boshen
  • 724
  • 7
  • 15
  • @asmmo This is a VS generated `main` function. _t for TCHAR version `main` function. It should work just like normal `main` function. – guan boshen May 31 '20 at 05:58
  • 1
    Unrelated: Rather than the `while(true)`, consider `join`ing `th`. – user4581301 May 31 '20 at 06:08
  • Consider placing the critical sections inside their own code block and using a [`std::scoped_lock`](https://en.cppreference.com/w/cpp/thread/scoped_lock) or [`std::lock_guard`](https://en.cppreference.com/w/cpp/thread/lock_guard), depending on what's available to you. – user4581301 May 31 '20 at 06:11
  • I don't see any deadlock there. Your question is unclear, care to explain how you come to the conclusions you present there? – Ulrich Eckhardt May 31 '20 at 06:33
  • 2
    Note that `while (true);` has undefined behaviour – Alan Birtles May 31 '20 at 06:47
  • @AlanBirtles: That's a completely useless statement in this context. – Ulrich Eckhardt May 31 '20 at 06:51
  • It might not be, could be the cause of the problem – Alan Birtles May 31 '20 at 06:53
  • Might be, but just dumping that here without any explanation or reference is useless. – Ulrich Eckhardt May 31 '20 at 07:28
  • @AlanBirtles It cannot run to `while(true)`, so it is irrelevant. See my edit and try it in VS 2013. It locks. – guan boshen May 31 '20 at 08:43
  • @UlrichEckhardt Em... Have a try first please if possible, before voting to close this thread. – guan boshen May 31 '20 at 08:51
  • Visual Studio 2013 support for C++11 isn't perfect. It is even disabled by default. I wouldn't be surprised if something didn't work. Or you could've messed up with something. – ALX23z May 31 '20 at 08:51
  • I installed VS2013 _just_ to try this out. I could not reproduce the problem. How are you determining a deadlock? (E.g., are you [accidentally freezing console output](https://superuser.com/a/952027/5396)?) The only way to solve this is for you to debug it - attach a debugger and see what's going on. – GManNickG May 31 '20 at 09:14
  • @ALX23z I installed Ubuntu just now and tried this in gcc 6. The code works without problem. I think this may be a VS 2013 bug. – guan boshen May 31 '20 at 09:16
  • @GManNickG Em... I am using 2013 Update 5. I debugged it, it blocks at `wait_until` function with no further information (code goes into Kernel). – guan boshen May 31 '20 at 09:18
  • 2
    Likewise. Strange. Does this reproduce with even fewer elements (is the thread needed)? What about a shorter sleep time? This does seem like a runtime bug. Perhaps related: https://stackoverflow.com/questions/54493041/unpredictable-behaviour-of-stdsleep-for-on-windows-10 – GManNickG May 31 '20 at 09:28
  • Have you tried debugging? – Alan Birtles May 31 '20 at 11:15
  • @GManNickG Thread is needed. It runs without problem when no thread involved. Honestly, VS 2013 does not fully support C++11, and I don't figure this out before. – guan boshen May 31 '20 at 13:13

1 Answers1

1

I think this is a bug in VS 2013 update 5. Using GCC 6.0 in Ubuntu 16.04.5 cannot reproduce this problem. Furthermore, It may be a bug related to std::this_thread::sleep_for function which causes the internal dead lock with std::mutex. So, use it with caution.

guan boshen
  • 724
  • 7
  • 15