2010-09-23 31 views
12

Có cách nào để dễ dàng giới hạn ứng dụng C/C++ với một lượng bộ nhớ cụ thể (30 mb hoặc hơn) không? Ví dụ: nếu ứng dụng của tôi cố hoàn thành tải một tệp 50MB vào bộ nhớ, nó sẽ chết/in thư và thoát/etc.Giới hạn sử dụng bộ nhớ C/C++ một cách giả tạo

Phải thừa nhận rằng tôi có thể liên tục kiểm tra mức sử dụng bộ nhớ cho ứng dụng, nhưng sẽ dễ dàng hơn một chút nếu nó chỉ chết nếu có lỗi ở trên.

Bất kỳ ý tưởng nào?

Nền tảng không phải là vấn đề lớn, windows/linux/bất kỳ trình biên dịch nào.

+0

Tại sao không chỉ kiểm tra kích thước của tệp? –

Trả lời

9

Đọc trang hướng dẫn sử dụng cho ulimit trên hệ thống Unix. Có một nội trang hệ vỏ, bạn có thể gọi trước khi khởi chạy tệp thực thi của bạn hoặc (trong phần 3 của hướng dẫn) một cuộc gọi API có cùng tên.

+3

Lưu ý rằng API 'ulimit()' đã lỗi thời. Thay vào đó, bạn muốn 'setrlimit()'. – bstpierre

+0

@bstpierre: Trang người đàn ông trên hộp Mac OS 10.5 của tôi không đề cập gì về điều đó (mặc dù 'setrlimit (2)' cũng có mặt và postdates 'ulimit (3)'). Bạn có biết những tiêu chuẩn nào tạo nên sự thay đổi không? – dmckee

+1

Trang người dùng trên hộp linux của tôi cho biết: 'CONFORMING TO SVr4, POSIX.1-2001. POSIX.1-2008 đánh dấu ulimit() là lỗi thời.' Xem ghi chú trên [trang người đàn ông trực tuyến] (http://www.opengroup.org/onlinepubs/9699919799/functions/ulimit.html#tag_16_630_13). – bstpierre

4

Ghi đè tất cả API malloc và cung cấp trình xử lý cho mới/xóa, để bạn có thể đặt giữ mức sử dụng bộ nhớ và ném ngoại lệ khi cần.

Bạn không chắc chắn điều này thậm chí còn dễ dàng hơn/tiết kiệm công sức hơn là chỉ giám sát bộ nhớ thông qua API do OS cung cấp.

+0

Tôi sẽ làm điều đó :) (đủ để móc HeapAlloc() win32 API) – ruslik

6

Trên Windows, bạn không thể đặt hạn ngạch cho việc sử dụng bộ nhớ của một quy trình trực tiếp. Tuy nhiên, bạn có thể tạo một đối tượng công việc Windows, đặt hạn ngạch cho đối tượng công việc, và sau đó gán quy trình cho đối tượng công việc đó.

5

Trong bash, sử dụng ulimit builtin:

bash$ ulimit -v 30000 
bash$ ./my_program 

Các -v mất 1K khối.

Cập nhật:

Nếu bạn muốn thiết lập này từ bên trong ứng dụng của bạn, sử dụng setrlimit. Lưu ý rằng trang người dùng cho số ulimit(3) nói rõ ràng rằng nó đã lỗi thời.

1

Bạn có thể giới hạn kích thước bộ nhớ ảo của quy trình của bạn bằng cách sử dụng giới hạn hệ thống. Nếu bạn xử lý vượt quá số tiền này, nó sẽ bị giết với một tín hiệu (SIGBUS tôi nghĩ).

Bạn có thể sử dụng một cái gì đó như:

#include <sys/resource.h> 
#include <iostream> 

using namespace std; 

class RLimit { 
public: 
    RLimit(int cmd) : mCmd(cmd) { 
    } 

    void set(rlim_t value) { 
     clog << "Setting " << mCmd << " to " << value << endl; 
     struct rlimit rlim; 
     rlim.rlim_cur = value; 
     rlim.rlim_max = value; 
     int ret = setrlimit(mCmd, &rlim); 
     if (ret) { 
      clog << "Error setting rlimit" << endl; 
     } 
    } 

    rlim_t getCurrent() { 
     struct rlimit rlim = {0, 0}; 
     if (getrlimit(mCmd, &rlim)) { 
      clog << "Error in getrlimit" << endl; 
      return 0; 
     } 
     return rlim.rlim_cur; 
    } 
    rlim_t getMax() { 
     struct rlimit rlim = {0, 0}; 
     if (getrlimit(mCmd, &rlim)) { 
      clog << "Error in getrlimit" << endl; 
      return 0; 
     } 
     return rlim.rlim_max; 
    } 

private: 
    int mCmd; 
}; 

Và sau đó sử dụng nó như thế:

RLimit dataLimit(RLIMIT_DATA); 
dataLimit.set(128 * 1024); // in kB 
clog << "soft: " << dataLimit.getCurrent() << " hard: " << dataLimit.getMax() << endl; 

thực hiện này có vẻ hơi dài dòng nhưng nó cho phép bạn dễ dàng và sạch sẽ thiết lập giới hạn khác nhau (xem ulimit -a).

Các vấn đề liên quan