在C ++程序中并行化C代码模块

时间:2017-09-27 15:35:44

标签: c++ c qt variables global

我的情况: 我在微控制器上运行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;
}

有更好的方法吗?

1 个答案:

答案 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都以一个完全干净的环境开始。

有一个/很多/更多的分叉权利比我认为合理地作为这个问题的答案。

第三个选项是从外部驱动程序,以便某些监视器脚本或程序启动多个并行实例,每个实例都通过测试列表的子集线性运行。理想情况下,内置功能,以便监视器可以按需调度测试和负载平衡。