sanjay
sanjay

Reputation: 755

c++ 11 Threads different behaviour on linux and windows

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mx;
void some_function()
{
    while(1)
    {
        std::lock_guard<std::mutex> mx_guard(mx);
        std::cout << "some_function()\n";
    }
}

void some_other_function()
{
    while(1)
    {
        std::lock_guard<std::mutex> mx_guard(mx);
        std::cout << "some_other_function\n";
    }
}

int main()
{
    std::thread t1(some_function);
    std::thread t2 = std::move(t1); //t2 will be joined

    t1 = std::thread(some_other_function);

    if(t2.joinable())
    {
        std::cout << "t2 is joinable()\n";
        t2.join(); //calling join for t1
    }
    if(t1.joinable())
    {
        std::cout << "t1 is joinable()\n";
        t1.join();
    }
    return 0;
}

I have different output for this program on windows and linux. On windows using visual studio 13 compiler i get the following output.

some_function()
some_other_function
some_function()
some_other_function
some_function()
some_other_function
some_function()
some_other_function
some_function()
some_other_function
some_function()
some_other_function

But on linux using gcc the output is different

some_function()
some_function()
some_function()
some_function()
some_function()
some_function()
some_function()
some_other_function
some_other_function
some_other_function
some_other_function
some_other_function
some_other_function
some_other_function

On windows two threads print one by one but on linux it's not the same behavior. Use of mutex on linux does not synchronize. How to synchronize on linux?

Upvotes: 1

Views: 2004

Answers (1)

kfsone
kfsone

Reputation: 24249

A mutex is simply a lock for preventing concurrent access to a shared resource, in this case std::cout. And in both cases, only one thread is writing to std::cout at a time. While it's possible that under some circumstances unlocking a mutex may result in waking another task, it is not something you should expect or rely on unless you are responsible for the OS/scheduler code yourself.

The mutex is restricting access to std::cout: If you run the same code without the lock-guard you're likely to see garbled/mixed output on one OS or the other.

The fact that you're seeing something like that in Visual Studio is purely coincidental and is not guaranteed, and the fact that you are seeing something else under Linux is more likely to be about differences in how IO is performed than how threads operate.

I'm speculating as to what you are actually trying to do here, but I suspect you want a condition_variable and notify_one. However, you again should not assume that it will round-robin.

Also, joinable() tests whether the threads are running, join() waits for them to stop, but since your threads are in a permanent loop, the first call to join() will hang forever.

--- EDIT ---

When I run your code under Visual Studio 2015 with /O2, I get the same output as you report for Linux.

Upvotes: 5

Related Questions