#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
В чем ошибка?
C/C++
Неправильный вывод программы C++
У вас второй поток выводит результат быстрее чем он был изменен в первом потоке. Второй поток не связан блокировками с первым.
На моем компьютере первый поток успевает обработать j и выводит 300000. А если поставить на первый миллисекундную задержку, то выводит 3.
На моем компьютере первый поток успевает обработать j и выводит 300000. А если поставить на первый миллисекундную задержку, то выводит 3.
Ошибка в программе заключается в том, что переменная "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, поскольку это дает вам больше контроля над параллелизмом
Чтобы исправить это, вы должны заменить "мьютекс" на "Мьютекс" в строке, где он используется в качестве параметра шаблона 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
Похожие вопросы
- Создание таблицы в консоли вывода программы. С++
- Составить программу c++ срочно пожалуйста
- Остановка программы c++
- Как уменьшить время работы программы? C++
- Составить программу C++, с помощью switch/case
- Написание программы C++ Массивы
- Написать программу. C++
- Помогите написать программу C++
- Помогите, пожалуйста, написать программу C++!
- Написать программу C++