Multithreading C++\Cli Parallel::For with thread局部变量-错误:参数太多
尝试使用tread局部变量实现我的第一个Multithreading C++\Cli Parallel::For with thread局部变量-错误:参数太多,multithreading,parallel-processing,c++-cli,Multithreading,Parallel Processing,C++ Cli,尝试使用tread局部变量实现我的第一个Parallel::For循环,以对循环结果求和。我的代码是基于一个例子,在Visual C++ 2010中,由W. Saumweber,D. Louis(德语),Ch. 33,P.804)。 由于Parallel::For调用中出现语法错误,我在实现中陷入困境。从左到右,错误如下:a)需要类型说明符,b)泛型类“System::Func”的参数太多,c)指向成员的指针对托管类无效,d)没有运算符“&”匹配这些操作数 根据这本书,我创建了一个包含数据的集合
Parallel::For
循环,以对循环结果求和。我的代码是基于一个例子,在Visual C++ 2010中,由W. Saumweber,D. Louis(德语),Ch. 33,P.804)。
由于Parallel::For
调用中出现语法错误,我在实现中陷入困境。从左到右,错误如下:a)需要类型说明符,b)泛型类“System::Func
”的参数太多,c)指向成员的指针对托管类无效,d)没有运算符“&”匹配这些操作数
根据这本书,我创建了一个包含数据的集合列表编号
,该集合受方法computeSumScore
中执行的计算的约束,该方法由方法sumScore
中的Parallel::For
例程调用
下面我粘贴了课程中.cpp部分的完整代码,以展示我所拥有的。数据收集“数字
”可能看起来有点混乱,但这是由于课程的有机发展和我不断学习的结果
// constructor
DataCollection::DataCollection(Form1^ f1) // takes parameter of type Form1 to give acces to variables on Form1
{
this->f1 = f1;
}
// initialize data set for parallel processing
void DataCollection::initNumbers(int cIdx)
{
DataStructure^ number;
numbers = gcnew List<DataStructure^>();
for (int i = 0; i < f1->myGenome->nGenes; i++)
{
number = gcnew DataStructure();
number->concentrationTF = f1->myOrgan->cellPtr[cIdx]->concTFA[i];
number->stringA->AddRange(f1->myGenome->cStruct[i]->gString->GetRange(0, f1->myGenome->cChars));
number->stringB->AddRange(f1->myGenome->cStruct[i]->pString);
if (f1->myGenome->cStruct[i]->inhibitFunc)
number->sign = -1;
else
number->sign = 1;
numbers->Add(number);
}
}
// parallel-for summation of scores
double DataCollection::sumScore()
{
Parallel::For<double>(0, numbers->Count, gcnew Func<double>(this, &GenomeV2::DataCollection::initSumScore),
gcnew Func<int, ParallelLoopState^, double, double>(this, &GenomeV2::DataCollection::computeSumScore),
gcnew Action<double>(this, &GenomeV2::DataCollection::finalizeSumScore));
return summation;
}
// returns start value
double DataCollection::initSumScore()
{
return 0.0;
}
// perform sequence alignment calculation
double DataCollection::computeSumScore(int k, ParallelLoopState^ status, double tempVal)
{
int nwScore;
if (numbers[k]->concentrationTF > 0)
{
nwScore = NeedlemanWunsch::computeGlobalSequenceAlignment(numbers[k]->stringA, numbers[k]->stringB);
tempVal = Mapping::getLinIntMapValue(nwScore); // mapped value (0-1)
tempVal = (double) numbers[k]->sign * tempVal * numbers[k]->concentrationTF;
}
else
tempVal = 0.0;
return tempVal;
}
// locked addition
void DataCollection::finalizeSumScore(double tempVal)
{
Object^ myLock = gcnew Object();
try
{
Monitor::Enter(myLock);
summation += tempVal;
}
finally
{
Monitor::Exit(myLock);
}
}
//构造函数
DataCollection::DataCollection(Form1 ^f1)//获取Form1类型的参数以访问Form1上的变量
{
这->f1=f1;
}
//初始化并行处理的数据集
void DataCollection::initNumbers(int-cIdx)
{
数据结构^编号;
编号=gcnew List();
对于(inti=0;imyGenome->nGenes;i++)
{
number=gcnew DataStructure();
编号->浓缩TF=f1->肌细胞->细胞PTR[cIdx]->浓缩TFA[i];
number->stringA->AddRange(f1->myGenome->cStruct[i]->gString->GetRange(0,f1->myGenome->cChars));
数字->字符串B->添加范围(f1->myGenome->cStruct[i]->pString);
如果(f1->myGenome->cStruct[i]->inhibitFunc)
数字->符号=-1;
其他的
数字->符号=1;
数字->添加(数字);
}
}
//分数总和的并行计算
双重数据收集::sumScore()
{
并行::For(0,number->Count,gcnew Func(this,&GenomeV2::DataCollection::initSumScore),
gcnew Func(this,&GenomeV2::DataCollection::computeSumScore),
gcnew操作(this,&GenomeV2::DataCollection::finalizeSumScore));
返回求和;
}
//返回起始值
双重数据收集::initSumScore()
{
返回0.0;
}
//执行序列比对计算
double DataCollection::computeSumScore(int k,ParallelLoopState^状态,double tempVal)
{
int nwScore;
if(数字[k]->concentrationTF>0)
{
nwScore=NeedlemanWunsch::computeGlobalSequenceAlignment(数字[k]->stringA,数字[k]->stringB);
tempVal=Mapping::getLinIntMapValue(nwScore);//映射值(0-1)
tempVal=(双精度)数字[k]->符号*tempVal*数字[k]->concentrationTF;
}
其他的
tempVal=0.0;
返回临时值;
}
//锁定加法
无效数据收集::finalizeSumScore(双临时值)
{
对象^myLock=gcnew Object();
尝试
{
监视器::输入(myLock);
总和+=临时值;
}
最后
{
监视器::退出(myLock);
}
}
一旦这个问题得到解决,我需要确保调用的函数(computeGlobalSequenceAlignment和getLinIntMapvalue)是线程安全的,并且程序不会在访问相同(静态)变量的多个踏板上停止。但是这需要先工作
希望您能帮助我。Hans Passant在评论中回答了我的问题(包括完整的方法名,添加逗号)。但是我无法将我的问题标记为已回答,因此此答案是为了结束问题。初始化委托需要使用完整的方法名。因此它是
gcnew Func(this,&DataCollection::initSumScore)
。您可能会收到关于第二个Func的IntelliSense警告,像一个bug一样嘎嘎作响。编译器将接受它。包括命名空间和类。编译时出现以下错误:1>DataCollection.cpp(46):错误C2676:二进制“&”:“GenomeV2::DataCollection ^const”未定义此运算符或到预定义运算符1>DataCollection.cpp可接受的类型的转换(46):错误C3350:“System::Action”:委托构造函数需要2个参数1>,其中1>[1>T=double 1>]在这后面加一个逗号。很好的捕获(oops)。代码可以编译。IntelliSense仍然认为它不完全正确。