Nói chung, tôi không nghĩ bạn có thể không may. (Một số hệ điều hành có thể cung cấp cho nó, nhưng tôi không biết những cái tôi biết hỗ trợ này.)
Tài liệu tham khảo cho giới hạn tài nguyên: getrlimit
từ POSIX 2008.
Lấy ví dụ về giới hạn CPU RLIMIT_CPU
.
- Nếu quá trình vượt quá giới hạn mềm, nó sẽ được gửi
SIGXCPU
- Nếu quá trình vượt quá giới hạn cứng, nó sẽ trở nên đơn giản
SIGKILL
Nếu bạn có thể wait()
trong chương trình của mình, bạn có thể biết nếu nó bị giết bởi SIGXCPU
. Nhưng bạn không thể phân biệt được một người được SIGKILL
phái đi vì vi phạm giới hạn cứng từ một vụ giết người cũ đơn giản từ bên ngoài. Hơn nữa, nếu chương trình xử lý XCPU
, bạn thậm chí sẽ không nhìn thấy điều đó từ bên ngoài.
Điều tương tự cho RLIMIT_FSIZE
. Bạn có thể thấy SIGXFSZ
từ wait()
trạng thái nếu chương trình không xử lý nó. Nhưng một khi vượt quá giới hạn kích thước tệp, điều duy nhất xảy ra là I / O tiếp tục thử kiểm tra giới hạn đó một lần nữa sẽ nhận được EFBIG
- điều này sẽ bị chương trình xử lý (hoặc không, không may). Nếu chương trình xử lý SIGXFSZ
, giống như trên - bạn sẽ không biết về nó.
RLIMIT_NOFILE
? Chà, bạn thậm chí không nhận được tín hiệu. open
và bạn bè chỉ cần quay lại EMFILE
chương trình. Nó không bị làm phiền, vì vậy nó sẽ thất bại (hoặc không) theo bất kỳ cách nào nó được mã hóa để thất bại trong tình huống đó.
RLIMIT_STACK
? Tốt cũ SIGSEGV
, không thể được phân biệt với điểm số của các lý do khác để được giao một. (Bạn sẽ biết rằng đó là những gì đã giết quá trình, mặc dù, từ wait
trạng thái.)
RLIMIT_AS
và RLIMIT_DATA
sẽ chỉ thực hiện malloc()
và một vài người khác bắt đầu thất bại (hoặc nhận SIGSEGV
nếu giới hạn AS bị tấn công trong khi cố gắng mở rộng ngăn xếp trên Linux). Trừ khi chương trình được viết rất tốt, có thể nó sẽ thất bại khá ngẫu nhiên vào thời điểm đó.
Vì vậy, nói tóm lại, các lỗi này không khác biệt rõ ràng với các lý do tử vong của quá trình khác, vì vậy bạn không thể chắc chắn hoặc có thể được xử lý hoàn toàn từ chương trình trong trường hợp nó quyết định nếu / khi / cách thức tiến hành, không phải bạn từ bên ngoài.
Điều tốt nhất bạn có thể làm theo như tôi biết là viết một chút mã cho chương trình của bạn, chờ đợi trên đó và:
- kiểm tra trạng thái thoát để phát hiện
SIGXCPU
và SIGXFSZ
(AFAIK, các tín hiệu đó sẽ chỉ được HĐH tạo ra cho các vấn đề giới hạn tài nguyên). Tùy thuộc vào nhu cầu chính xác của bạn, bạn có thể cho rằng điều đó SIGKILL
và SIGSEGV
cũng liên quan đến giới hạn tài nguyên, nhưng đó là một chút khó khăn.
- nhìn vào những gì bạn có thể nhận được từ
getrusage(RUSAGE_CHILDREN,...)
việc triển khai của bạn để có gợi ý về những thứ khác.
Các cơ sở dành riêng cho hệ điều hành có thể tồn tại để trợ giúp ở đây (có thể là những thứ như ptrace
trên Linux, hoặc Solaris dtrace
), hoặc có thể là các kỹ thuật loại trình gỡ lỗi, nhưng điều đó sẽ còn gắn chặt hơn với việc triển khai cụ thể của bạn.
(Tôi hy vọng người khác sẽ trả lời bằng một số điều kỳ diệu mà tôi hoàn toàn không biết.)
malloc
nhưng thật không may, nó không giải quyết được vấn đề bộ nhớ nói chung, vì nói chung đó là về cuộc gọi hệ thốngbrk
(tôi có đúng không?).