Как увеличить размер стека python
Перейти к содержимому

Как увеличить размер стека python

  • автор:

Настройка рекурсии в Python

Функция sys.getrecursionlimit() возвращает текущее значение предела рекурсии, максимальную глубину стека интерпретатора Python. Этот предел предотвращает бесконечную рекурсию от переполнения стека языка C и сбоя Python. Это значение может быть установлено с помощью sys.setrecursionlimit() .

sys.setrecursionlimit(limit) :

Функция sys.setrecursionlimit() устанавливает максимальную глубину стека интерпретатора Python для ограничения. Этот предел предотвращает бесконечную рекурсию от переполнения стека языка C и сбоя Python.

Максимально возможный предел зависит от платформы. Пользователю может потребоваться установить более высокий предел, если у него есть программа, которая требует глубокой рекурсии и платформа, которая поддерживает более высокий предел. Это следует делать с осторожностью, так как слишком высокий лимит может привести к сбою.

Если новый предел глубины стека слишком низкий на текущей глубине рекурсии, возникает исключение RecursionError .

Изменено в Python 3.12: Ограничение рекурсии теперь применяется только к коду Python. Встроенные функции не используют ограничение рекурсии, но защищены другим механизмом, который не позволяет рекурсии вызывать сбой виртуальной машины.

  • ОБЗОРНАЯ СТРАНИЦА РАЗДЕЛА
  • События аудита CPython
  • Функция argv модуля sys
  • Имя используемой OS
  • Различные сведения о версии Python
  • Каталоги и пути интерпретатора Python
  • Кодировка, используемая Python
  • Настройка рекурсии
  • Функции трассировки и профилирования кода модуля sys
  • Функция breakpointhook() модуля sys
  • Объекты stdin, stdout, stderr модуля sys
  • Функции exc_info() и exception() модуля sys
  • Функция getrefcount() модуля sys
  • Атрибуты path и path_hooks модуля sys
  • Список загруженных и скомпилированных модулей
  • Атрибут float_info модуля sys
  • Атрибут int_info модуля sys
  • Атрибут maxsize модуля sys
  • Атрибут byteorder модуля sys
  • Функция exit() модуля sys
  • Функция getsizeof() модуля sys
  • Атрибут dont_write_bytecode модуля sys
  • Функция warnoptions() модуля sys
  • Переменные last_type, last_value, last_traceback
  • Переменная sys.last_exc модуля sys
  • Функция set_asyncgen_hooks() модуля sys
  • Функция get_coroutine_origin_tracking_depth() модуля sys

Как увеличить размер стека в Python?

У меня есть программа на Python, которая использует пользовательскую DLL. Эта DLL вылетает из-за переполнения стека. Это переполнение происходит не из-за неправильной рекурсивной функции, а из-за больших выделений в стеке с помощью alloca().

Я хочу увеличить размер стека, чтобы избавиться от этой ошибки. Есть ли какой-то способ сделать это?

Поделиться Источник 14 января 2010 в 21:17

4 ответа

Модуль thread в Python позволяет указать новый размер стека для новых потоков. Попробуйте установить его на значение, которое вам кажется достаточно большим, а затем выполнить работу этой DLL в новом потоке.

Поделиться 14 января 2010 в 21:36

Как отмечено в некоторых связанных вопросах как здесь, обычно не очень хорошая идея играть с размером стека, чтобы расширить глубину рекурсии, но вот код, который показывает, как увеличить стек до этого эффекта. С python 3.5 на системе Windows 10 x64, он демонстрирует очень глубокую рекурсию, которая обычно невозможна (обычно допустимый предел рекурсии в моей ситуации, кажется, 993). Я не знаю, насколько большой должен быть стек для этого примера, но на моей машине, с половиной размера, указанного ниже, python вылетает.

import sys import threading class SomeCallable: def __call__(self): try: self.recurse(99900) except RecursionError: print("Booh!") else: print("Hurray!") def recurse(self, n): if n > 0: self.recurse(n-1) SomeCallable()() # recurse in current thread # recurse in greedy thread sys.setrecursionlimit(100000) threading.stack_size(0x2000000) t = threading.Thread(target=SomeCallable()) t.start() t.join() 

Поделиться 12 ноября 2015 в 00:39

Функции в dll не могут иметь контроля над размером стека, доступным при их выполнении (если вы не запускаете новые потоки под управлением вашей библиотеки).

Если dll является пользовательской, то вы не можете выделять на куку, а не на стек (или статически выделять, если это уместно), и остановить проблему таким образом?

Поделиться 14 января 2010 в 21:28

Наверное, программа может изменить размер стека только новых потоков или процессов (например, функция CreateThread в Windows). Поскольку Python (и API Win32 для Python) не демонстрируют такой функциональности, вам следует заменить выделение стека на куче памяти. Или есть конкретная причина использовать стек?? Если вам действительно нужно использовать alloca , вы можете создать отдельный поток для выполнения DLL-кода (что, на мой взгляд, излишне затратно).

РЕДАКТИРОВАТЬ: Исправление — Python позволяет устанавливать размер стека при создании новых потоков (см. thread.stack_size)

Использование рекурсии более 1000 раз

Я новичок в программировании на Python(мой 1 язык программирования). Решал задачу №12 из Проекта Эйлера. Я использовал рекурсию в функции, но к сожалению, чтобы решить задачу, придётся использовать рекурсию более 1000 раз. Хотел бы узнать, как решить эту задачу по-прежнему используя рекурсию, для того чтобы знать об этом в будущем. Как можно улучшить код и что вы думаете о моих названиях переменных и функции? Вот так звучит задача : Последовательность треугольных чисел образуется путем сложения натуральных чисел. К примеру, 7-ое треугольное число равно 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. Первые десять треугольных чисел: 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, . Перечислим делители первых семи треугольных чисел: 1: 1 3: 1, 3 6: 1, 2, 3, 6 10: 1, 2, 5, 10 15: 1, 3, 5, 15 21: 1, 3, 7, 21 28: 1, 2, 4, 7, 14, 28 Как мы видим, 28 — первое треугольное число, у которого более пяти делителей. Каково первое треугольное число, у которого более пятисот делителей? Вот мой код:

def tringle_number(x): if x == 1: return 1 else: return x + tringle_number(x-1) for i in range(1, 900): a.append(tringle_number(i)) print(a) need = 0 all_number = [1] count = 0 for item in a: number = 0 for j in range(1, 100000): if item % j == 0: count = j number += 1 if number == 100: for items in all_number: need += 1 if need == 1: all_number.append(item) else: continue else: continue print(all_number[1]) 

Отслеживать

543 5 5 серебряных знаков 14 14 бронзовых знаков

задан 18 дек 2020 в 18:56

Решения на Python

Первым делом нужно отметить, что Python, являясь языком интерпретируемым, а не компилируемым, не способен обеспечить должную скорость работы в большинстве задач. Эталонных решений на Python нет и не предполагается, поэтому используйте этот язык на свой страх и риск. Возможно, решение придётся переписывать на другом языке. Эмпирические наблюдения показывают, что Python использует до 10 раз больше памяти и около 10–100 раз больше времени по сравнению с аналогичным решением на C/C++.

Некоторые внешние библиотеки (numpy и др.) способны улучшить эти показатели, однако использование библиотек, отличных от стандартных, не допускается тестирующей системой. В отличие от компилируемых языков, где использование внешних библиотек приводит к ошибке компиляции, интерпретатор Python успешно осуществляет запуск такой программы и порождает исключение на строке import numpy (или при подключении другой библиотеки). Это, в свою очередь, трактуется тестирующей системой как ошибка во время исполнения и приводит к вердикту Run-time Error.

В Python стандартный размер программного стека невелик — меньше 1000 вызовов — чего вполне достаточно для нерекурсивной программы практически любого реалистичного уровня сложности, но часто недостаточно для рекурсивных алгоритмов. Увеличить размер стека можно при помощи функции sys.setrecursionlimit , однако нужно иметь в виду, что более предпочтительным решением проблемы будет итеративная версия алгоритма (возможно, с использованием структуры данных стек), поскольку кадр программного стека (stack frame) в Python может занимать много памяти (следовательно, требовать много времени).

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *