2014-04-19 48 views
2

我目前正在處理一次加載和轉換多個圖像的管道。由於這種情況同時發生在很多圖像上(1440),內存佔用很大。因此,我試圖實現基於setrlimit的內存管理系統,但它似乎並沒有影響衍生線程(std :: thread),因爲它們會高興地忽略限制 - 我知道這是因爲調用getrlimit()線程函數 - 並最終導致我的程序被殺害。以下是我用於設置限制的代碼:setrlimit()不影響衍生的std :: threads

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()的最開始被調用。

+2

除了「實際問題」之外,您爲什麼認爲這是正確的解決方案?當然,正確的解決方案是不要一次啓動多個線程或加載多少圖像,或者無論您需要做什麼來限制內存使用量?假設'setr​​limit'實際上工作,將會發生什麼事情是你的進程要麼被殺死,要麼無法在「隨機」某個地方分配內存,這顯然是一個相當可怕的方式來處理這個問題... –

+0

我確實檢查可用內存加載之前。如果沒有剩餘內存,則至少在理論上加載暫停。我的問題是線程忽略了現有的限制,我不知道爲什麼或如何解決它。 –

+0

請顯示一個最小的可構建示例來演示該問題。 –

回答

1

的問題是很難找到,因爲它由兩個完全獨立的部分組成:

  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。