【问题标题】:Does getenv cache the result?getenv 是否缓存结果?
【发布时间】:2012-05-17 13:33:27
【问题描述】:

我在代码中多次调用getenv(多次调用),因此我看到了优化的潜力。我的问题是,getenv 是否以某种方式在内部缓存结果,还是在每次调用时查询环境变量?

我已经分析了代码,getenv 不是瓶颈,但如果它更有效,我仍然想更改它。

作为一个附带问题,可以在程序运行时更改环境变量吗?我不这样做,所以在我的情况下缓存结果是安全的,这只是好奇。

【问题讨论】:

  • 如何确定没有用户会在运行时更改环境变量?

标签: c++ optimization environment-variables


【解决方案1】:

环境变量通常存在于给定进程的内存中,因此没有什么可以缓存在那里,它们随时可用。

至于更新,运行进程的任何组件都可以调用putenv 来更新环境,如果您预计会发生这种情况,则不应长时间缓存它。

【讨论】:

  • 你说的任何人是什么意思?外部进程?
  • @hmjd:我的意思是正在运行的进程的组件。外部应用程序无法更改我知道的任何操作系统上正在运行的进程的环境。
  • 这也是我的理解。您可能需要修改您的答案以明确这一点。
  • Windows(我认为是 XP 和更高版本)确实设法改变了环境。启动一个 cmd shell,set。转到我的电脑-> 属性-> 高级并更改路径。回到cmd shell,再次运行set
  • @JimR:设置输出不变,%MYVAR% 也不变,只有新启动的 cmd shell 有新值
【解决方案2】:

我怀疑它会缓存结果,环境变量可能会因调用而异。您可以自己实现该缓存:

#include <map>
#include <iostream>
#include <string>
#include <stdexcept>
#include <cstdlib>


class EnvCache {
public:
    const std::string &get_env(const std::string &key) {
        auto it = cache_entries.find(key);
        if(it == cache_entries.end()) {
            const char *ptr = getenv(key.c_str());
            if(!ptr)
                throw std::runtime_error("Env var not found");
            it = cache_entries.insert({key, ptr}).first;
        }
        return it->second;
    }

    void clear() {
        cache_entries.clear();
    }
private:
    std::map<std::string, std::string> cache_entries;
};

int main() {
    EnvCache cache;
    std::cout << cache.get_env("PATH") << std::endl;
}

如果您修改环境变量,您可以使缓存条目无效。您也可以直接映射到const char*,但这取决于您。

【讨论】:

    【解决方案3】:

    进程从创建新进程的进程继承环境。这是保存在内存中的。

    确实,在 C 和 C++ 中,您可以定义 main 以具有包含环境的额外参数 - 请参阅 http://www.gnu.org/software/libc/manual/html_node/Program-Arguments.html#Program-Arguments

    此外,您可以使用extern char **environ; 访问包含环境的数组。 (这是空终止的)

    因此您不需要缓存。环境变量作为数组保存在内存中。

    【讨论】:

    • C++ 不提供包含环境的主要功能。那是一个 gcc 扩展。
    • 我认为虽然 C 确实为 main 定义了环境变量,但没有人就它的标准达成一致,这意味着在实践中它完全没用,应该用 getenv() 替换。
    • @smerlin,它不仅仅是一个 gcc(或 GNU)扩展,它是一个 unix 约定。 POSIX 标准将全局数组定义为访问环境的可移植方式,请参阅pubs.opengroup.org/onlinepubs/9699919799/functions/environ.html - 因此,如果在 POSIX 系统上使用 C++,它将起作用,与 GCC 无关。
    • @JonathanWakely:我谈到了主函数采用第三个参数,而不是全局变量。他自己的链接也提到它不是 POSIX 标准的一部分。 (POSIX.1 does not allow this three-argument form, so to be portable it is best to write main to take two arguments, and use the value of environ.)
    • @smerlin,是的,但这仍然是一个 unix 约定,而不是 gcc 特定的。 Ed Heal 链接到的 glibc 文档甚至是这样说的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-29
    相关资源
    最近更新 更多