我目前正在研究一次加载和转换多个图像的管道。由于这同时发生在许多图像上(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影响整个过程,所以我有点无能为力,为什么这些线程似乎不会受到影响。
编辑:顺便说一句,上面的函数在main()的最开头调用。
答案 0 :(得分:1)
这个问题很难找到,因为它由两个完全独立的组件组成:
我的可执行文件是使用-fomit-frame-pointer编译的。这将导致限制重置。请参阅以下示例:
/* 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。