discord icon
سرور دیسکورد گاردایران

پست های پیشنهاد شده

با سلام و خسته نباشید خدمت همه دوستان.

در این تاپیک نحوه محدود کردن منابع مصرفی توسط برنامه رو یاد میگیریم.

 

تابع getrlimit و setrlimit:

تابع getrlimit: یک پارامتر میگیره که نوع منبع (resource) هست و محدودیت فعلی اون منبع رو به شکل tuple برمیگردونه.

تابع setrlimit: دو پارامتر میگیره که اولی نوع منبع و دومی یک tuple که محدودیتی است که میخواهیم روی اون منبع بگذاریم.

 

محدود کردن مصرف CPU:

در محدود کردن مصرف CPU دو عدد وجود داره: soft limit و hard limit.

soft limit: وقتی میزان مصرف برنامه به این عدد برسه سیگنال SIGXCPU به برنامه ارسال میشه و عملی که به صورت پیشفرض برای این سیگنال تعریف شده خاتمه دادن (TERMINATE) برنامه هست. اگر این توسط برنامه نویس عوض بشه و برنامه در هنگام دریافت این سیگنال خاتمه پیدا نکنه و به مصرف کردن CPU ادامه بده هر یک ثانیه یک بار سیگنال SIGXCPU ارسال میشه تا زمانی که مصرف به hard limit برسه.

hard limit: به برنامه سیگنال SIGKILL ارسال میشه و برنامه kill میشه.

 

import resource
import signal

CPU_TIME_LIMIT = 20 # 20 seconds

def cpu_time_exceeded(signo, frame):
  print("CPU exceeded!")
  raise SystemExit(1)

soft, hard = resource.getrlimit(resource.RLIMIT_CPU)
resource.setrlimit(resource.RLIMIT_CPU, (CPU_TIME_LIMIT, hard))
signal.signal(signal.SIGXCPU, cpu_time_exceeded)

while True:
  pass

توضیح کد:

۱- مقدار پیشفرض soft و hard رو با تابع getrlimit میگیریم. (اگر مقدار soft یا hard برابر با -1 باشد یعنی محدودیتی تعریف نشده)

۲- با استفاده از تابع setrlimit محدودیت را برای میزان مصرف CPU تنظیم میکنیم. (در پارامتر دوم تابع setrlimit یک tuple ارسال میکنیم که مقدار اول soft limit و مقدار دوم hard limit است)

۳- با استفاده از تابع signal کار پیشفرضی که برای سیگنال SIGXCPU تعریف شده را با یک تابع جایگزین میکنیم. یعنی وقتی سیگنال SIGXCPU دریافت شود تابع cpu_time_exceeded فراخوانی می شود.

۴- یک حلقه بی نهایت تعریف شده و چون برای مصرف CPU محدودیت تعریف کردیم بعد از 20 ثانیه از برنامه خارج می شود.

 

محدود کردن مصرف RAM: 

اگر برنامه بیشتر از عدد مشخص شده (به بایت) از حافظه استفاده کند ارور MemoryError به وجود می آید.

import signal
import resource

MEMORY_LIMIT = 10 # 10 bytes

soft, hard = resource.getrlimit(resource.RLIMIT_AS)
resource.setrlimit(resource.RLIMIT_AS, (MEMORY_LIMIT, hard))

data = list(range(0, 200000)) # MemoryError

توضیح کد:

۱- مانند مرحله قبل ابتدا مقادیر پیشفرض soft limit و hard limit گرفته میشه و بعد با کمک تابع setrlimit مصرف رم به ۱۰ بایت محدود میشه.

۲- با استفاده از تابع range اعداد ۰ تا ۲۰۰۰۰۰ برگردانده میشوند و به خاطر اینکه میزان مصرف حافظه این لیست بیشتر از ۱۰ بایت است برنامه ارور MemoryError میده.

 

 

حداکثر سایز فایلی که برنامه میتونه ایجاد کنه:

با این محدودیت میتونیم برنامه رو محدود کنیم که نتونه فایل هایی که حجمشون بیشتر از عددی  هست که بهش دادیم (‌به بایت) بسازه.

در صورتی که برنامه بخواد فایلی بسازه که حجمش از محدودیتی که تعیین کردیم بیشتر باشه سیگنال SIGXFSZ به برنامه ارسال میشه و به صورت پیشفرض برنامه خطای OSError میده.

import signal
import resource

FILE_SIZE_LIMIT = 20 # 20 bytes

soft, hard = resource.getrlimit(resource.RLIMIT_FSIZE)
resource.setrlimit(resource.RLIMIT_FSIZE, (FILE_SIZE_LIMIT, hard))

with open("test.txt", "w") as f:
  f.write("a"*21) # OSError: [Errno 27] File too large

توضیح کد:

۱- محدودیت حجم فایل بر روی ۲۰ بایت تنظیم میشه.

۲- وقتی بخواهیم فایلی بزرگتر از ۲۰ بایت ایجاد کنیم برنامه ارور OSError میده.

 

import signal
import resource

FILE_SIZE_LIMIT = 40 # 40 bytes

def file_size_exceeded(signo, frame):
  print("File too large")
  raise SystemExit(1)

soft, hard = resource.getrlimit(resource.RLIMIT_FSIZE)
resource.setrlimit(resource.RLIMIT_FSIZE, (FILE_SIZE_LIMIT, hard))
signal.signal(signal.SIGXFSZ, file_size_exceeded)

with open("file.txt", "w") as f:
	f.write("a" * 50) # File too large & exit program

توضیح کد:

اینجا تابع file_size_exceeded به جای کار پیشفرض فراخوانی میشه.

به اشتراک گذاری این ارسال


لینک به ارسال
به اشتراک گذاری در سایت های دیگر

برای ارسال دیدگاه یک حساب کاربری ایجاد کنید یا وارد حساب خود شوید

برای اینکه بتوانید دیدگاهی ارسال کنید نیاز دارید که کاربر سایت شوید

ایجاد یک حساب کاربری

برای حساب کاربری جدید در سایت ما ثبت نام کنید. عضویت خیلی ساده است !

ثبت نام یک حساب کاربری جدید

ورود به حساب کاربری

دارای حساب کاربری هستید؟ از اینجا وارد شوید

ورود به حساب کاربری