#c #multithreading #stdthread
Вопрос:
Я работаю над программой, которая выполняется в цикле for. Поскольку аргументы и выходные данные для каждого вызова уникальны, я мог бы распараллелить вызовы внутри цикла. Однако это работает неправильно. Ниже приведен пример программы, иллюстрирующей эту проблему
#include <iostream>
#include <cstdlib>
#include <thread>
#include <mutex>
void subProg1(intamp; ii, doubleamp; emod, doubleamp; prat);
using namespace std;
int main()
{
int imax = 4;
int ii;
double emod[4];
double prat[4];
std::thread threadpointer[4];
emod[0] = 10;
emod[1] = 20;
emod[2] = 30;
emod[3] = 40;
prat[0] = 0.1;
prat[1] = 0.2;
prat[2] = 0.3;
prat[3] = 0.4;
for (ii=0;ii<imax;ii ) {
cout<<" In main Program " <<endl;
cout<<" count = : "<<ii<<" emod = : "<<emod[ii]<<" pRat = : "<<prat[ii]<<endl;
threadpointer[ii] = std::thread(subProg1,ref(ii),ref(emod[ii]),ref(prat[ii]));
//threadpointer[ii].join();
}
for (ii=0;ii<imax;ii ) {
threadpointer[ii].join();
}
}
void subProg1(intamp; ii, doubleamp; emod, doubleamp; prat)
{
cout <<" In SubProgram "<<endl;
cout<<" count = : "<<ii<<" emod = : "<<emod<<" pRat = : "<<prat<<endl;
}
Результат этого прогона выглядит следующим образом
In main Program
count = : 0 emod = : 10 pRat = : 0.1
In SubProgram
In main Program
count = : 1 emod = : count = : 1 emod = : 20 pRat = : 0.2
10 pRat = : 0.1
In SubProgram
In main Program
count = : 2 emod = : 20 pRat = : 0.2
count = : 2 emod = : 30 pRat = : 0.3
In SubProgram
In main Program
count = : 3 emod = : 40 pRat = : 0.4
count = : 3 emod = : 30 pRat = : In SubProgram
count = : 2 emod = : 40 pRat = : 0.4
0.3
Я понимаю, что звонки будут несинхронизированы. Однако индекс и значения emod и prat, соответствующие этому индексу, также не совпадают. Правильные значения должны быть
count = :0 emod = : 10 pRat = :0.1
count = :1 emod = : 20 pRat = :0.2
count = :2 emod = : 30 pRat = :0.3
count = :3 emod = : 40 pRat = :0.4
Интересно, чего мне не хватает. Любая помощь будет признательна
Комментарии:
1. Захват
ii
по значению, в противном случае, еслиii
захват по ссылке, на него влияетцикл in for.
2. Как говорит @rafix07, в вашем коде есть условие гонки, поскольку все созданные потоки пытаются получить доступ
ii
одновременноfor
с тем, как цикл изменяет его.3. Спасибо. вот в чем была проблема
Ответ №1:
Не передавайте счетчик по ссылке, так как при увеличении main он также будет увеличиваться в потоке. Передайте его по значению.
void subProg1(int ii, doubleamp; emod, doubleamp; prat);