Как я увеличиваю размер стека в Python

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

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

8
задан Philippe Beaudoin 14 January 2010 в 21:17
поделиться

3 ответа

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

Редактировать: Коррекция - Python позволяет устанавливать размер стека при создании новых потоков (см. Thread.Stack_size )

2
ответ дан 5 December 2019 в 11:25
поделиться

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

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

2
ответ дан 5 December 2019 в 11:25
поделиться

Обычно я предлагаю попробовать функцию startToDataFrame () , но я считаю, что это будет довольно сложно, потому что она не очень хорошо структурирована для начала.

Я бы порекомендовал работать с этой функцией:

xmlToList(books)

Одна проблема состоит в том, что на книгу приходится несколько авторов, поэтому вам нужно будет решить, как с этим справиться при структурировании кадра данных.

После того, как вы решили, что делать с вопросом нескольких авторов, то это довольно прямо вперед, чтобы превратить вашу книгу список в кадр данных с функцией ldply () в plyr (или просто использовать lapply и преобразовать возвращаемое значение в data.frame с помощью do.call («rbind...»).

Вот полный пример (исключая автора):

library(XML)
books <-  "w3schools.com/xsl/books.xml"
library(plyr)
ldply(xmlToList(books), function(x) { data.frame(x[!names(x)=="author"]) } )

   .id        title.text title..attrs year price   .attrs
 1 book  Everyday Italian           en 2005 30.00  COOKING
 2 book      Harry Potter           en 2005 29.99 CHILDREN
 3 book XQuery Kick Start           en 2003 49.99      WEB
 4 book      Learning XML           en 2003 39.95      WEB

Вот как он выглядит с включенным автором. Вы должны использовать ldply в этом случае, так как список «зазубренный»... приложение не может обработать это должным образом. [В противном случае вы можете использовать lapply с rbind.fill (также любезно предоставлено Хэдли), но зачем беспокоиться, когда plyr автоматически делает это для вас?]:

ldply(xmlToList(books), data.frame)

   .id        title.text title..attrs              author year price   .attrs
1 book  Everyday Italian           en Giada De Laurentiis 2005 30.00  COOKING
2 book      Harry Potter           en        J K. Rowling 2005 29.99 CHILDREN
3 book XQuery Kick Start           en      James McGovern 2003 49.99      WEB
4 book      Learning XML           en         Erik T. Ray 2003 39.95      WEB
     author.1   author.2   author.3               author.4
1        <NA>       <NA>       <NA>                   <NA>
2        <NA>       <NA>       <NA>                   <NA>
3 Per Bothner Kurt Cagle James Linn Vaidyanathan Nagarajan
4        <NA>       <NA>       <NA>                   <NA>
-121--2518637-

Этого на самом деле не должно произойти. Загрузка считается отдельным запросом, который должен выполняться в фоновом режиме независимо от родительской страницы после вызова. Как именно вы запускаете запрос на загрузку? По простой ванильной ссылке или ссылке, которая (неправильно) инициирует ajaxical запрос на запуск загрузки?

В любой путь, вы, по крайней мере, явно хотите иметь возможность возобновить загрузки. В этом случае при загрузке необходимо отправить по крайней мере заголовки ответов Accept-Ranges , ETag и Last-Modified . Затем клиент может запросить возобновление загрузки, отправив заголовки запросов If-Range и Range с соответствующим идентификатором файла и указанным диапазоном байтов, которые можно использовать в комбинации с RandomStartFile для отправки оставшихся байтов. Дополнительную информацию и образец сервлета можно найти в этой статье .

Такова теория. В вашем конкретном случае, это немного сложнее, так как вы копируете файлы на лету. Сначала необходимо записать застежку -молнию во временную папку локальной дисковой файловой системы сервера, а затем выполнить из нее поток и, наконец, удалить файл только после успешного завершения загрузки (т.е. out.close () не вызвал IOException ). Вы можете идентифицировать связанную застежку -молнию с помощью параметра запроса или pathinfo или, возможно, ключа в сессии.

Обновление : согласно вашему обновлению: Я, честно говоря, не знаю и никогда не испытывал его, но, по крайней мере, могу сказать, что вы не единственный, кто пострадал от этой проблемы . По крайней мере,реализация описанных выше возможностей возобновления может быть решением этой конкретной проблемы, поскольку Firefox автоматически возобновит загрузку, не затрагивая неполную часть.

Update 2 : После небольшой мысли после прочтения вашего обновления и поведения браузера, это выглядит так, что существует довольно большой промежуток времени между запуском фактического запроса и прибытием заголовков ответа. Я не знаю точных деталей, как вы загружаете файлы, но это выглядит как то, что есть затраты времени на сбор ЗАСТЕЖКИ -МОЛНИИ файлов (может быть, вы загружаете их из сетевой файловой системы или базы данных заранее?) и что вы устанавливаете/посылаете заголовки ответов только после вы собрали все ЗАСТЕЖКИ -МОЛНИИ файлы. Попробуйте установить заголовки и выполнить команду output.flush () перед выполнением дорогостоящей задачи. Таким образом браузер получит заголовки как можно скорее и будет знать, что он может ожидать.

-121--4950823-

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

7
ответ дан 5 December 2019 в 11:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: