首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >玛雅线程造成崩溃

玛雅线程造成崩溃
EN

Stack Overflow用户
提问于 2015-04-01 03:38:37
回答 2查看 1.4K关注 0票数 0

我已经启动了一个自动保存脚本编辑器脚本(使用Maya 2014),但是它非常不稳定,如果在保存的同时发生了一些事情,它可能会崩溃。我还意识到即使不保存也会发生崩溃,所以我试图找出实际的问题是什么,最后几乎没有剩下任何代码,但仍然能够复制它。

我对代码的想法是运行一个后台线程,在其中它将循环和备份脚本的间隔,但每秒钟检查一个值,以确保它没有被暂停或取消(取消将停止循环)。

我认为这个问题与后台线程在Maya中的工作方式有关,因为如果加载/关闭脚本编辑器窗口,或者切换呈现视图设置上的选项卡,它可能会崩溃(至少与选中的精神射线有关,因为加载选项卡所用的时间似乎比默认呈现器长)。我想还有其他的方法,但这些方法确实很容易找到。

在while循环中把它转到time.sleep()之后,我真的不明白它为什么会导致崩溃。我还使用了一个不同的睡眠函数来执行while time.time()>startTime+1,以确保它不是时间模块,但它仍然会导致崩溃。

如果有人想尝试使用AutoSave.start()启动线程,如果您继续加载和关闭脚本编辑器窗口,那么最终应该会得到一个运行时错误(即R6025纯虚拟函数调用)。这可能需要多次尝试,但似乎最终都会发生。

代码语言:javascript
代码运行次数:0
运行
复制
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中的代码,每当脚本编辑器窗口关闭时,这些代码都会运行。我认为这可能与我修改过的版本的保存有关,然后尝试同时保存,但它仍然崩溃,循环中什么都没有发生。

代码语言:javascript
代码运行次数:0
运行
复制
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];
        }
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-04-01 06:06:44

尝试将对print的调用包装在pymel.mayautils.executeDeferredmaya.utils.executeDeferred中,以便在主UI线程上执行它。

如果您继续加载和关闭脚本编辑器窗口,您最终应该会得到一个运行时错误(即R6025纯虚拟函数调用)。这可能需要多次尝试,但似乎最终都会发生。

我能够证实玛雅2012的这种行为,我怀疑它是否是特定的版本。

我敢打赌,您对print的测试调用实际上是导致Maya崩溃的原因,因为尽管print通常只是一条python语句,但是Maya还是有某种挂钩来用您正在打印的字符串更新脚本编辑器的输出窗口(以及潜在的命令响应栏),这些字符串都运行在主UI线程上。

来自Autodesk知识文章"Python和线程“

Maya和Maya架构并不是线程安全的.如果在主线程之外调用Maya命令,则会抛出异常,并且使用主线程以外的OpenMaya API会产生不可预见的副作用。

通过将您的print语句传递给pymel.mayautils.executeDeferred,我(至少到目前为止,谁知道Maya ;-)无法造成崩溃。

代码语言:javascript
代码运行次数:0
运行
复制
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

票数 3
EN

Stack Overflow用户

发布于 2019-02-25 02:19:07

代码语言:javascript
代码运行次数:0
运行
复制
import threading
import time
import maya.utils as utils
run_timer = True
run_num = 0
def example(interval = 10):
    global run_timer;global run_num;
    def your_function_goes_here():
        print "hello",run_num
        run_num +=1
    while run_timer:
        time.sleep(interval)
        utils.executeDeferred(your_function_goes_here)

t = threading.Thread(None, target = example, args = (1,) )
t.start()

# stop :
# run_timer = False
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29382456

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档