Sceptical Jule
Sceptical Jule

Reputation: 917

Inconsistencies in the output while reading and writing simultaneously

Why is this code producing an inconsistent output of the reader function?

#include <cstdio>
#include <thread>
#include <mutex>

std::mutex mu;
int i = 0;

void writeThread()
{
    for (int j = 0; j < 1000; ++j)
    {
        std::lock_guard<std::mutex> lock(mu);
        printf ("write i: %d\n", ++i);
    }
}

void readThread()
{
    for (int j = 0; j < 1000; ++j)
        printf ("Read i = %d\n", i);
}

int main()
{
    std::thread t(writeThread);
    std::thread z(readThread);
    t.join();
    z.join();
    return 0;
}

I sometimes get something like:

write i: 996
write i: 997
Read i = 980 <--- wrong reader output starting here
Read i = 998
Read i = 998
write i: 998
Read i = 998
write i: 999
Read i = 999

Is only the output wrong or do I really need a mutex in the reader function?

Upvotes: 0

Views: 67

Answers (1)

NathanOliver
NathanOliver

Reputation: 180500

Is only the output wrong or do I really need a mutex in the reader function?

The output is not wrong, if you have two or more threads accessing a variable and and at least one of them is a writer then you need to provide synchronization. Since readThread does not wait for WriteThread to write to i you have a race condition. This is undefined behavior and any output you get is "correct". To fix this you need to add std::lock_guard<std::mutex> lock(mu); to readThread like

void readThread()
{
    for (int j = 0; j < 1000; ++j)
    {
        std::lock_guard<std::mutex> lock(mu);
        printf ("Read i = %d\n", i);
    }
}

If you have more readers then you have writers you can use a std::shared_mutex which will allow multiple readers to read at the same time but will block all readers and other writers when one of the writers needs to write.

Upvotes: 1

Related Questions