C/C++

Неправильный вывод программы C++

#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
using namespace std;

mutex Mutex;

int foo(int refer)
{
lock_guard<mutex> lock(Mutex);
int sum = 0;
for(int i = 0; i < 1000000; ++i)
sum += refer;
return sum;
}

int main()
{
int j = 3;
thread a([&] {
j = foo(j);
});
thread b([&] {
cout << "j = " << j << endl;
});
int flag = 0;
this_thread::sleep_for(chrono::milliseconds(1000));
a.join();
b.join();
return 0;

вывод: j = 3, вместо j = 3000000
В чем ошибка?
У вас второй поток выводит результат быстрее чем он был изменен в первом потоке. Второй поток не связан блокировками с первым.
На моем компьютере первый поток успевает обработать j и выводит 300000. А если поставить на первый миллисекундную задержку, то выводит 3.
AS
Amcix Siken Basanov
51 416
Лучший ответ
Ошибка в программе заключается в том, что переменная "Mutex" определена неправильно. Вместо имени переменной "Mutex" используется ключевое слово "mutex". Это приводит к тому, что программа использует необъявленную переменную, что приводит к неопределенному поведению.

Чтобы исправить это, вы должны заменить "мьютекс" на "Мьютекс" в строке, где он используется в качестве параметра шаблона lock_guard. Кроме того, вы не инициализируете значение "j" перед передачей его в поток a, поэтому результатом "j" всегда будет 3, а не 3000000.

Вот исправленная версия:

#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
using namespace std;

mutex Mutex;

int foo(int refer)
{
lock_guard<mutex> lock(Mutex);
int sum = 0;
for(int i = 0; i < 1000000; ++i)
sum += refer;
return sum;
}

int main()
{
int j = 3000000;
thread a([&] {
j = foo(j);
});
thread b([&] {
cout << "j = " << j << endl;
});
a.join();
b.join();
return 0;
}

Это даст ожидаемый результат "j = 3000000".

Кроме того, рассмотрите возможность использования std::atomic вместо использования std::mutex и std::lock_guard, поскольку это дает вам больше контроля над параллелизмом
Владислав Михалёв Знаю про atomic, но решил протестировать работу mutex. Переменная j инициализирована и равна 3,
Владислав Михалёв К тому же, я не понял, где я использую mutex вместо Mutex lock_guard<mutex> lock(Mutex); - здесь все правильно. К тому же программа прибавляет к sum refer и мне не понятно почему после 1000000 прибавлений refer к sum sum отстается начальным значением j