我的情况: 我在微控制器上运行C代码。为了测试这段代码,我用C ++编写了一个检查C函数的测试程序。由于测试功能非常慢,我想要并行完成整个过程。但是,我没有多少经验。
例如,我在C中有一个程序模块,如下所示:
/* c-code: */
static int a=0;
void set_a(int value){
a = value;
}
void inc_a(void){
a++;
}
int get_a(void){
return a;
}
现在我想在C ++中并行化这些函数。但是,我对全局变量a感到困扰,这在我的情况下是无法避免的。 在QT环境中,我想执行"异步运行"函数inc_a。这有效,但没有改善:
int foo(int somevalue){
set_a(somevalue);
inc_a();
return get_a();
}
int myinput = 1,myoutput;
QFuture<int> future = QtConcurrent::run(foo,myinput);
future.waitForFinished();
myoutput = future.result();
这就是我想要的:
int myinput1 = 1,myoutput1;
int myinput2 = 8,myoutput2;
QFuture<int> future1 = QtConcurrent::run(foo,myinput1);
QFuture<int> future2 = QtConcurrent::run(foo,myinput2);
future1.waitForFinished();
future2.waitForFinished();
myoutput1 = future1.result();
myoutput2 = future2.result();
所以我的第一个问题是(确定):变量a(在C中)现在在两个线程中是否相同是正确的吗?如果没有,我必须再次查看我的代码。如果是,我如何尽可能优雅地解决问题?我想过创建两个具有相同功能的C程序模块。然而,这使程序非常不友好:
/* c-code: */
static int a1=0;
void set_a1(int value){
a1 = value;
}
void inc_a1(void){
a1++;
}
int get_a1(void){
return a1;
}
static int a2=0;
void set_a2(int value){
a2 = value;
}
void inc_a2(void){
a2++;
}
int get_a2(void){
return a2;
}
有更好的方法吗?
答案 0 :(得分:1)
你运气不好。 理想情况下,重写你的可测试资产,使其包含一个包含所有那些讨厌的全局变量的状态结构,也许你会逃脱它。
Vroomfondel还建议,如果可以将代码编译为C ++,则将有问题的C代码包装在命名空间中可能会隐藏问题。 您可以创建任意数量的名称空间,而不是您想要的并行线程:
namespace TEST1
{
#include "offender.c"
}
namespace TEST2
{
#include "offender.c"
}
RetCode DoTest(int instance, TestId testid)
{
switch (instance)
{
case 1: return TEST1::DoTest(testid);
case 2: return TEST2::DoTest(testid);
}
return OUT_OF_RANGE;
}
如果您的目标确实使用全局状态且无法更改,那么您可以考虑使用分叉。
在一个分支中,为孩子运行当前状态的完整副本,并且他们都恢复了足够的信息,因此您知道哪个是孩子,哪个是所有者。您还可以设置管道以便它们相互通信。测试完成后,它会传输其状态并退出其分叉过程。
Forks对测试套件非常有用,因为每个fork都以一个完全干净的环境开始。
有一个/很多/更多的分叉权利比我认为合理地作为这个问题的答案。
第三个选项是从外部驱动程序,以便某些监视器脚本或程序启动多个并行实例,每个实例都通过测试列表的子集线性运行。理想情况下,内置功能,以便监视器可以按需调度测试和负载平衡。