2015-04-01 2 views
0

Я начал сценарий сценария сценария автосохранения (с использованием Maya 2014), но он действительно нестабилен и может произойти сбой, если что-то произойдет одновременно с сохранением. Я также просто понял, что аварии произойдут даже тогда, когда они не будут сохранены, поэтому я попытался найти, что представляет собой настоящая проблема, и закончил тем, что остался только один код, но все же смог его воспроизвести.Maya threading вызывает сбой

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

Я предполагаю, что проблема связана с тем, как фоновые потоки работают в Maya, поскольку это может привести к сбою при загрузке/закрытии окна редактора сценариев или переключении вкладок в настройках представления рендеринга (по крайней мере, с выбранным Mental Ray, поскольку он, кажется, занимает больше загружаемых вкладок, чем средство рендеринга по умолчанию). Я предполагаю, что есть другие способы, но это те, которые очень легко найти.

После того, как он достиг всего time.sleep() в цикле while, мне действительно не имеет смысла, почему он должен быть причиной сбоя. Я также использовал другую функцию сна, которая делает while time.time()>startTime+1, чтобы убедиться, что это не временный модуль, но он по-прежнему вызывает сбои.

Вот отрезанный код, если кто-то захочет попробовать его, как только вы начнете поток с AutoSave.start(), если вы постоянно загружаете и закрываете окно редактора сценариев, вы должны в конечном итоге получить ошибку времени выполнения (это говорит о чистой виртуальной функции R6025 вызов). Это может занять несколько попыток, но в любом случае это всегда происходит.

import threading, time 
import pymel.core as pm 

class AutoSaveThread(object): 
    def __init__(self): 
     thread = threading.Thread(target=self.run, args=()) 
     thread.daemon = True 
     thread.start() 
    def run(self): 
     while True: 
      time.sleep(1) 
      print "Open and close the script editor enough times and this will crash" 

class AutoSave: 
    @classmethod 
    def start(self): 
     AutoSaveThread() 

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

Для записи здесь приведен код кода, встроенный в Maya, который будет всегда запускаться всякий раз, когда окно редактора сценариев будет закрыто. Я думал, что это может иметь какое-то отношение к моей модифицированной версии ее сохранения, а затем это попытка сохранить в то же время, но она все еще падает, и ничего не происходит в цикле.

global proc syncExecuterBackupFiles(){ 
    global string $gCommandExecuter[]; 
    global string $executerBackupFileName; 

    if(`optionVar -q saveActionsScriptEditor`) { 
     // clear the script editor temp dir first before writing temp files 
     string $scriptEditorTempDir = (`internalVar -userPrefDir` + "scriptEditorTemp/"); 
     string $tempFiles[] = `getFileList -folder $scriptEditorTempDir`; 
     string $file; 
     for ($file in $tempFiles) { 
      sysFile -delete ($scriptEditorTempDir + $file); 
     } 

     // save all the executer control text to files 
     int $i = 0; 
     for($i = 0; $i < size($gCommandExecuter); $i++) { 
      cmdScrollFieldExecuter -e -storeContents $executerBackupFileName $gCommandExecuter[$i]; 
     } 
    } 
} 

ответ

3

Попробуйте обертывание ваш вызов print в pymel.mayautils.executeDeferred или maya.utils.executeDeferred так, что она выполняется в основном потоке пользовательского интерфейса.


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

Я был в состоянии подтвердить это поведение на майя 2012 года, и я сомневаюсь, что это версия.

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

От Autodesk Knowledge article "Python and threading":

Maya API и Maya команд архитектуры не поточно-. Команды майя вызывают исключение, если они выходят за пределы основного потока, а использование OpenMaya API из потоков, отличных от основного, имеет непредвиденные побочные эффекты.

Передавая свой print заявление pymel.mayautils.executeDeferred Я (по крайней мере до сих пор, кто знает с Майей ;-)) не смогли привести к аварии.

import threading, time 
import pymel.core as pm 

import pymel.mayautils # like maya.utils, for executeDeferred 

# Set to False at any time to allow your threads to stop 
keep_threads_alive = True 

def wrapped_print(): 
    print "Opening and closing the script editor shouldn't make this crash\n" 

class AutoSaveThread(object): 
    def __init__(self): 
     thread = threading.Thread(target=self.run) 
     thread.start() 
    def run(self): 
     while keep_threads_alive: 
      time.sleep(1) 
      pymel.mayautils.executeDeferred(wrapped_print) 

... 

Единственный побочный эффект упаковки конкретно print заявления является то, что он больше не перекликается с панелью команд реагирования. Если сохранение этого поведения важно для вас, просто используйте вместо него pymel.mel.mprint.

+0

Спасибо большое, ха-ха, я попробовал обернуть другие биты в 'executeDeferred', но я не думал, что это нужно для' print'. Полный код по-прежнему будет терпеть крах при загрузке/закрытии редактора сценария во время его сохранения (сомневаюсь, что я могу сделать это, но предупредить людей), но пока все работает нормально. Любопытно, что я всегда делал 'maya.utils.executeDeferred' и не знал о' pymel.mayautils', есть ли какие-то преимущества друг от друга? Кроме того, лучше всего использовать 'pymel.mel.mprint', чем' print', если загружается pymel? – Peter

+0

@Peter Вы должны иметь возможность сделать эту работу, не беспокоясь о сбоях, но это зависит от того, как и когда вы захватываете данные из редактора сценариев. – systemexit

+1

@Peter 'pymel.mayautils.executeDeferred' является оберткой для' mel.utils.executeDeferred', которая также обрабатывается, когда Maya запускается в пакетном режиме, а 'print' - это инструкция python, тогда как' mprint' делает вызов 'майа .mel.eval' использовать печать Мела. Связи pymel, которые я связывал, объясняют различия на обоих довольно хорошо, и еще лучше, источник для обоих доступен. См. 'Python/lib/site-packages/pymel/mayautils.py' и' Python/lib/site-packages/pymel/core/language.py' соответственно в вашей установке Maya. – systemexit

Смежные вопросы