因此,基本上,我试图在C ++代码中设置一个环境变量以强制将线程数设置为1。我正在使用多个机器学习库,这些库默认情况下使用OpenMP
,并且可以强制在通过设置以下环境变量来实现单线程模式:OMP_NUM_THREADS=1
这是我的问题。我想从我正在构建的库中设置此环境变量。
当我从主函数设置环境变量(针对正在构建的库的可执行链接)时,它会按预期工作(程序执行期间仅使用1个线程):
auto implPtr = FRVT_11::Interface::getImplementation();
implPtr->initialize(CONFIG_DIR);
char ompEnv[]="OMP_NUM_THREADS=1";
putenv( ompEnv );
// More code
但是,如果我尝试从正在构建的库中设置环境变量(例如,从getImplementation
函数中设置),则使用的线程数为4,而不是1:
// This does not work
std::shared_ptr<FRVT_11::Interface> FRVT_11::Interface::getImplementation() {
char ompEnv[]="OMP_NUM_THREADS=1";
putenv( ompEnv );
return std::make_shared<MyImplementation>();
}
有什么主意为什么会这样?我正在构建和运输库,因此我需要从库中设置线程数。
答案 0 :(得分:1)
您的“库函数”版本是未定义的行为。
您的“主要功能”版本也可能是未定义的行为,这是额外的好处,但您尚未意识到。
从putenv(3)
手册页的Linux版本开始(其他OS实现可能是相同的):
[putenv()的参数]指向的字符串成为 环境,因此更改字符串会更改环境。
那是您巨大的,鸣喇叭的警钟:您最好甚至不要再想用10英尺长的杆触碰这根弦,因为它现在已成为环境的一部分。
在您的共享库版本中:
char ompEnv[]="OMP_NUM_THREADS=1";
此数组是函数中的局部变量。因此,此函数返回时,此数组将被销毁。但是,此数组也作为参数传递给putenv()
。总计:此函数返回后,您的环境变量之一立即变为悬空指针。
没有足够的信息来确定性地证明您的“主要功能”版本也是未定义的行为,但很有可能。