பைதான் மறுசுழற்சி வரம்பை சரிபார்த்து மாற்றவும் (எ.கா. sys.setrecursionlimit)

வணிக

பைத்தானில், மறுபயன்பாடுகளின் எண்ணிக்கைக்கு அதிகபட்ச வரம்பு உள்ளது (அதிகபட்ச எண்ணிக்கையிலான மறுபயன்பாடுகள்). அதிக எண்ணிக்கையிலான அழைப்புகளுடன் ஒரு சுழற்சி செயல்பாட்டை இயக்க, வரம்பை மாற்றுவது அவசியம். நிலையான நூலகத்தின் sys தொகுதியில் உள்ள செயல்பாடுகளைப் பயன்படுத்தவும்.

ஸ்டேக் அளவினால், மறுபயன்பாடுகளின் எண்ணிக்கை வரையறுக்கப்பட்டுள்ளது. சில சூழல்களில், ஸ்டாண்டர்டு லைப்ரரியின் ரிஸோர்ஸ் மாட்யூல் அதிகபட்ச ஸ்டாக் அளவை மாற்ற பயன்படுகிறது (இது உபுண்டுவில் வேலை செய்தது, ஆனால் விண்டோஸ் அல்லது மேக்கில் அல்ல).

பின்வரும் தகவல்கள் இங்கே கொடுக்கப்பட்டுள்ளன.

  • தற்போதைய எண்ணிக்கையிலான மறுபயன்பாடுகளின் மேல் வரம்பைப் பெறுங்கள்:sys.getrecursionlimit()
  • மறுபயன்பாடுகளின் எண்ணிக்கையின் மேல் வரம்பை மாற்றவும்:sys.setrecursionlimit()
  • அடுக்கின் அதிகபட்ச அளவை மாற்றவும்:resource.setrlimit()

மாதிரி குறியீடு உபுண்டுவில் இயங்குகிறது.

தற்போதைய மறுபயன்பாட்டு வரம்பைப் பெறுங்கள்: sys.getrecursionlimit ()

தற்போதைய மறுபயன்பாட்டு வரம்பை sys.getrecursionlimit () உடன் பெறலாம்.

import sys
import resource

print(sys.getrecursionlimit())
# 1000

எடுத்துக்காட்டில், அதிகபட்ச எண்ணிக்கையிலான மறுபயன்பாடுகள் 1000 ஆகும், இது உங்கள் சூழலைப் பொறுத்து மாறுபடலாம். நாம் இங்கு இறக்குமதி செய்யும் வளம் பின்னர் பயன்படுத்தப்படும், ஆனால் விண்டோஸில் அல்ல என்பதை நினைவில் கொள்க.

உதாரணமாக, பின்வரும் எளிய சுழற்சி செயல்பாட்டைப் பயன்படுத்துவோம். ஒரு நேர்மறை முழு எண் n ஒரு வாதமாக குறிப்பிடப்பட்டால், அழைப்புகளின் எண்ணிக்கை n மடங்காக இருக்கும்.

def recu_test(n):
    if n == 1:
        print('Finish')
        return
    recu_test(n - 1)

நீங்கள் மேல் வரம்பை விட அதிகமாக திரும்ப திரும்ப செய்ய முயற்சித்தால் ஒரு பிழை (RecursionError) எழுப்பப்படும்.

recu_test(950)
# Finish

# recu_test(1500)
# RecursionError: maximum recursion depth exceeded in comparison

Sys.getrecursionlimit () மூலம் பெறப்பட்ட மதிப்பு கண்டிப்பாக அதிகபட்ச எண்ணிக்கையிலான மறுசீரமைப்புகள் அல்ல, ஆனால் பைதான் மொழிபெயர்ப்பாளரின் அதிகபட்ச அடுக்கின் ஆழம், எனவே இந்த மதிப்பை விட மறுசீரமைப்புகளின் எண்ணிக்கை சற்று குறைவாக இருந்தாலும், ஒரு பிழை (RecursionError) உயர்த்தப்படும்

、 帰 限界 は 再 帰 の 限界 で は な 、 பைதான் イ ン タ ー リ リ タ の ス タ ッ ク の 深度 深度 で。
python – Max recursion is not exactly what sys.getrecursionlimit() claims. How come? – Stack Overflow

# recu_test(995)
# RecursionError: maximum recursion depth exceeded while calling a Python object

மறுபயன்பாட்டு வரம்பை மாற்றவும்: sys.setrecursionlimit ()

மறுபயன்பாடுகளின் எண்ணிக்கையின் மேல் வரம்பை sys.setrecursionlimit () மூலம் மாற்றலாம். மேல் வரம்பு ஒரு வாதமாக குறிப்பிடப்பட்டுள்ளது.

ஆழமான மறுசீரமைப்பைச் செய்ய அனுமதிக்கிறது.

sys.setrecursionlimit(2000)

print(sys.getrecursionlimit())
# 2000

recu_test(1500)
# Finish

குறிப்பிட்ட மேல் வரம்பு மிகச் சிறியதாகவோ அல்லது மிகப் பெரியதாகவோ இருந்தால், பிழை ஏற்படும். இந்த கட்டுப்பாடு (வரம்பின் மேல் மற்றும் கீழ் வரம்புகள்) சூழலைப் பொறுத்து மாறுபடும்.

வரம்பின் அதிகபட்ச மதிப்பு மேடையைப் பொறுத்தது. உங்களுக்கு ஆழ்ந்த மறுநிகழ்வு தேவைப்பட்டால், மேடையில் ஆதரிக்கப்படும் வரம்பிற்குள் ஒரு பெரிய மதிப்பை நீங்கள் குறிப்பிடலாம், ஆனால் இந்த மதிப்பு மிகப் பெரியதாக இருந்தால் விபத்தை ஏற்படுத்தும் என்பதை அறிந்து கொள்ளுங்கள்.
If the new limit is too low at the current recursion depth, a RecursionError exception is raised.
sys.setrecursionlimit() — System-specific parameters and functions — Python 3.10.0 Documentation

sys.setrecursionlimit(4)
print(sys.getrecursionlimit())
# 4

# sys.setrecursionlimit(3)
# RecursionError: cannot set the recursion limit to 3 at the recursion depth 1: the limit is too low

sys.setrecursionlimit(10 ** 9)
print(sys.getrecursionlimit())
# 1000000000

# sys.setrecursionlimit(10 ** 10)
# OverflowError: signed integer is greater than maximum

அதிகபட்ச எண்ணிக்கையிலான மறுசீரமைப்புகளும் அடுக்கு அளவால் வரையறுக்கப்பட்டுள்ளன, அடுத்து விளக்கப்பட்டது.

அடுக்கின் அதிகபட்ச அளவை மாற்றவும்: resource.setrlimit ()

Sys.setrecursionlimit () இல் ஒரு பெரிய மதிப்பு அமைக்கப்பட்டிருந்தாலும் கூட, மறுபயன்பாடுகளின் எண்ணிக்கை பெரியதாக இருந்தால் அது செயல்படுத்தப்படாமல் போகலாம். பின்வருமாறு ஒரு பிரிவு பிழை ஏற்படுகிறது.

sys.setrecursionlimit(10 ** 9)
print(sys.getrecursionlimit())
# 1000000000
recu_test(10 ** 4)
# Finish

# recu_test(10 ** 5)
# Segmentation fault

பைத்தானில், நிலையான நூலகத்தில் உள்ள வள தொகுதி அதிகபட்ச அடுக்கு அளவை மாற்ற பயன்படுத்தப்படலாம். இருப்பினும், ஆதார தொகுதி ஒரு யூனிக்ஸ்-குறிப்பிட்ட தொகுதி மற்றும் விண்டோஸில் பயன்படுத்த முடியாது.

Resource.getrlimit () உடன், வாதத்தில் குறிப்பிடப்பட்டுள்ள வளத்தின் வரம்பை (மென்மையான வரம்பு, கடின வரம்பு) டூப்பிளாகப் பெறலாம். இங்கே, resource.RLIMIT_STACK ஐ ஆதாரமாக குறிப்பிடுகிறோம், இது தற்போதைய செயல்முறையின் கால் ஸ்டாக்கின் அதிகபட்ச அளவைக் குறிக்கிறது.

print(resource.getrlimit(resource.RLIMIT_STACK))
# (8388608, -1)

எடுத்துக்காட்டில், மென்மையான வரம்பு 8388608 (8388608 B = 8192 KB = 8 MB) மற்றும் கடின வரம்பு -1 (வரம்பற்றது).

Resource.setrlimit () மூலம் நீங்கள் வளத்தின் வரம்பை மாற்றலாம். இங்கே, மென்மையான வரம்பு -1 ஆகவும் அமைக்கப்பட்டுள்ளது (வரம்பு இல்லை). வரம்பற்ற வரம்பைக் குறிக்க நீங்கள் நிலையான வளத்தைப் பயன்படுத்தலாம். RIM_INFINIT.

ஸ்டாக் அளவு மாற்றத்திற்கு முன் பிரிவு குறைபாடு காரணமாக செய்ய முடியாத ஆழ்ந்த மறுநிகழ்வை இப்போது செய்ய முடியும்.

resource.setrlimit(resource.RLIMIT_STACK, (-1, -1))

print(resource.getrlimit(resource.RLIMIT_STACK))
# (-1, -1)

recu_test(10 ** 5)
# Finish

இங்கே, ஒரு எளிய பரிசோதனைக்கு மென்மையான வரம்பு -1 (வரம்பு இல்லை) என அமைக்கப்பட்டுள்ளது, ஆனால் உண்மையில், அதை பொருத்தமான மதிப்புக்கு கட்டுப்படுத்துவது பாதுகாப்பானது.

கூடுதலாக, எனது மேக்கில் வரம்பற்ற மென்மையான வரம்பை அமைக்க முயற்சித்தபோது, ​​பின்வரும் பிழை ஏற்பட்டது.ValueError: not allowed to raise maximum limit
சுடோவுடன் ஸ்கிரிப்டை இயக்குவது உதவவில்லை. இது கணினியால் கட்டுப்படுத்தப்படலாம்.

ஒரு சூப்பர் யூசரின் பயனுள்ள யுஐடியுடன் ஒரு செயல்முறை எந்த வரம்பும் இல்லாமல் எந்த நியாயமான வரம்பையும் கோரலாம்.
இருப்பினும், கணினியால் விதிக்கப்பட்ட வரம்பை மீறிய ஒரு கோரிக்கை இன்னும் ஒரு ValueError ஐ ஏற்படுத்தும்.
resource.setrlimit() — Resource usage information — Python 3.10.0 Documentation

விண்டோஸில் ஆதார தொகுதி இல்லை, மேலும் சிஸ்டம் வரம்புகள் காரணமாக மேக்கால் அதிகபட்ச அடுக்கு அளவை மாற்ற முடியவில்லை. சில வழிகளில் ஸ்டாக் அளவை அதிகரிக்க முடிந்தால், பிரிவின் பிழையைத் தீர்க்க முடியும், ஆனால் இதை உறுதிப்படுத்த முடியவில்லை.