setrlimit () не влияет на порожденные 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 ().

2

Решение

Проблему было довольно трудно найти, поскольку она состояла из двух совершенно независимых компонентов:

  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
    
  2. В части обработки изображений я работаю с OpenCL. Видимо, реализация NVIDIA вызывает setrlimit и устанавливает предел в rlim_max.

1

Другие решения


По вопросам рекламы [email protected]