setrlimit()不影响派生的std::线程
setrlimit() not affecting spawned std::threads
我目前正在开发一个同时加载和转换多个图像的管道。由于这种情况同时发生在许多图像上(1440),因此内存占用相当大。因此,我试图实现一个基于setrlimit的内存管理系统,但它似乎不会影响派生的线程(std::thread),因为它们会很高兴地忽略限制——我知道这一点是因为在线程函数中调用了getrlimit()——并最终导致我的程序被终止。这是我用来设置限制的代码:
void setMemoryLimit(std::uint64_t bytes)
{
struct rlimit limit;
getrlimit(RLIMIT_AS, &limit);
if(bytes <= limit.rlim_max)
{
limit.rlim_cur = bytes;
std::cout << "New memory limit: " << limit.rlim_cur << " bytes" << std::endl;
}
else
{
limit.rlim_cur = limit.rlim_max;
std::cout << "WARNING: Memory limit couldn't be set to " << bytes << " bytes" << std::endl;
std::cout << "New memory limit: " << limit.rlim_cur << " bytes" << std::endl;
}
if(setrlimit(RLIMIT_AS, &limit) != 0)
std::perror("WARNING: memory limit couldn't be set:");
// included for debugging purposes
struct rlimit tmp;
getrlimit(RLIMIT_AS, &tmp);
std::cout << "Tmp limit: " << tmp.rlim_cur << " bytes" << std::endl; // prints the correct limit
}
我在用Linux。手册页指出setrlimit会影响整个过程,所以我有点不知道为什么线程似乎没有受到影响。
Edit:顺便说一下,上面的函数是在main()的开头调用的。
这个问题很难找到,因为它由两个完全独立的组件组成:
-
我的可执行文件是用-fomit框架指针编译的。这将导致限值的重置。参见以下示例:
/* rlimit.cpp */ #include <iostream> #include <thread> #include <vector> #include <sys/resource.h> class A { public: void foo() { struct rlimit limit; getrlimit(RLIMIT_AS, &limit); std::cout << "Limit: " << limit.rlim_cur << std::endl; } }; int main() { struct rlimit limit; limit.rlim_cur = 500 * 1024 * 1024; setrlimit(RLIMIT_AS, &limit); std::cout << "Limit: " << limit.rlim_cur << std::endl; std::vector<std::thread> t; for(int i = 0; i < 5; i++) { A a; t.push_back(std::thread(&A::foo, &a)); } for(auto thread : t) thread.join(); return 0; }
输出:
> g++ -std=c++11 -pthread -fomit-frame-pointer rlimit.cpp -o limit > ./limit Limit: 524288000 Limit: 18446744073709551615 Limit: 18446744073709551615 Limit: 18446744073709551615 Limit: 18446744073709551615 Limit: 18446744073709551615 > g++ -std=c++11 -pthread rlimit.cpp -o limit > ./limit Limit: 524288000 Limit: 524288000 Limit: 524288000 Limit: 524288000 Limit: 524288000 Limit: 524288000
-
对于图像处理部分,我使用OpenCL。显然,NVIDIA的实现调用了setrlimit,并将限制推到了rlim_max。
相关文章:
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 使用 std::variant<...时调用 BaseState 函数而不是派生函数>
- 使用 std::enable_if 限制派生类的模板参数时出现编译错误
- 指向基类派生类的 std::unique_ptr 的指针
- "std::shared_from_this"不能由其派生类继承吗?
- C++派生类重载函数(带有 std::function 参数)不可见
- C++ 事件管理器的回调,使用 std::function 和 std:bind 以及派生类作为参数
- 从组件的 std::type_index 获取派生最多的类型
- std::数组派生类聚合初始化
- 如何使用派生类类型数据初始化 std::shared_ptr?
- 自定义派生的 std::exception 类的 'what' 函数返回神秘的废话
- 抽象和派生与std::list相结合
- std::用派生类对象设置,但用gcc8.1设置基类比较器
- 派生自 std::exception 的类的赋值运算符
- 在 MSVC 中,从 std::string_view 派生的对象比较不明确
- 在从仅移动类型派生的类中定义析构函数在使用 std::vector emplace_back或push_back创建时会
- 派生 std::ofstream 和重载运算符<<
- 如何将 std::list of 派生类而不是 std::list of parent class 传递给函数
- 当用作非类型模板参数时,是否可以自动派生 std::array 的大小
- 无法通过引用 std::exception 来捕获从 std::exception 派生的类