У меня есть программа Python, которая использует сделанный на заказ DLL. Этот DLL отказывает из-за переполнения стека. Это переполнение не происходит из-за разложенной рекурсивной функции, но к большим выделениям на стеке с помощью alloca ().
Я хочу увеличить размер стека для избавлений от этой ошибки. Там какой-либо путь состоит в том, чтобы сделать это?
AFAIK Программа может изменить размер стека только новых потоков или процессов (Windows » CreateThread функции). В качестве Python (и API Win32 API для Python) не подвергается такому функциональности, вы предпочитаете заменить распределение стека с помощью памяти кучи. Или есть ли определенная причина использования стека ?? Если вы действительно имеют ALLOCA ALLOCA
Вы можете создать отдельный поток для выполнения DLL-кода (который я думаю).
Редактировать: Коррекция - Python позволяет устанавливать размер стека при создании новых потоков (см. Thread.Stack_size )
функции в dll не могут иметь никакого контроля над размером стека, доступным, когда они выполняются (если вы не порождаете новые потоки под управлением вашей библиотеки).
, Если dll является пользовательским, то разве, вы не можете выделить на "куче", а не стеке (или статически выделить, если соответствующий), и останавливают проблему тот путь?
Обычно я предлагаю попробовать функцию 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 ()
перед выполнением дорогостоящей задачи. Таким образом браузер получит заголовки как можно скорее и будет знать, что он может ожидать.
Модуль потока python позволяет указать новый размер стека для новых потоков. Попробуйте установить значение, которое, по вашему мнению, достаточно велико, и затем выполнить работу этой DLL в новом потоке.