首页 > 解决方案 > 从库 C++ 中设置环境变量

问题描述

所以基本上我试图在我的 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>();
}

任何想法为什么会这样?我正在构建和运送库,所以我需要从库中设置线程数。

标签: c++multithreadingenvironment-variablesopenmp

解决方案


您的“库函数”版本是未定义的行为。

作为额外奖励,您的“主要功能”版本也可能是未定义的行为,但您还没有意识到这一点。

putenv(3)手册页的 Linux 版本(其他操作系统实现可能相同):

[putenv() 的参数] 指向的字符串成为环境的一部分,因此更改字符串会改变环境。

那是你的大喇叭,警钟:你最好不要再想触碰这根弦,即使是用一根 10 英尺长的杆子,因为它现在是环境的一部分。

在您的共享库版本中:

char ompEnv[]="OMP_NUM_THREADS=1";

该数组是函数中的局部变量。因此,当此函数返回时,此数组将被销毁。但是这个数组也作为参数传递给putenv(). 总计:一旦此函数返回,您的环境变量之一现在就是一个悬空指针。

没有足够的信息可以最终证明您的“主要功能”版本也是未定义的行为,但也很有可能。


推荐阅读