Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Nuke(Python)中取消正在执行的写入节点_Python_Multithreading_Render_Nodes_Nuke - Fatal编程技术网

如何在Nuke(Python)中取消正在执行的写入节点

如何在Nuke(Python)中取消正在执行的写入节点,python,multithreading,render,nodes,nuke,Python,Multithreading,Render,Nodes,Nuke,我一直在用Python编写Nuke渲染管理器,但遇到了一个问题: nuke.cancel()。 我的python脚本创建一个主类并连接到一个服务器(用Java编写),然后进入一个无限循环,每次获得一个新任务(以JSON对象的形式)。它得到的每个循环都会打开一个脚本?查找写入节点并执行它们。为了向服务器报告进度,我添加了回调: nuke.addBeforeFrameRender(lambda:self.\u pre\u frame\u render()) 和 nuke.addAfterFrameR

我一直在用Python编写Nuke渲染管理器,但遇到了一个问题:
nuke.cancel()。
我的python脚本创建一个主类并连接到一个服务器(用Java编写),然后进入一个无限循环,每次获得一个新任务(以JSON对象的形式)。它得到的每个循环都会打开一个脚本?查找写入节点并执行它们。为了向服务器报告进度,我添加了回调:
nuke.addBeforeFrameRender(lambda:self.\u pre\u frame\u render())
nuke.addAfterFrameRender(lambda:self.\u post\u frame\u render())
在哪里

要在服务器上启用
cancel
方法,我有一个单独的线程,在渲染处于活动状态时运行,并等待“cancel”请求

class CancelHandler(threading.Thread):
    def __init__(self, input_socket, cancel_callback):
        threading.Thread.__init__(self)
        self.cancel_set = threading.Event()
        self.run_set = threading.Event()
        self._input_socket = input_socket
        self._cancel_callback = cancel_callback

    def run(self):
        while True:
            if self.run_set.is_set():
                msg_raw = recv_msg(self._input_socket)
                msg = json.loads(msg_raw)
                if 'mode' in msg and msg['mode'] == 'cancel':
                    print msg_raw
                    self.cancel_set.set()
                    self.run_set.clear()
                    self._cancel_callback()
cancel\u回调
定义为

def _cancel_callback(self):
        nuke.cancel()
        self._is_canceled = True
在循环开始之前,我启动
CancelHandler
线程,在每次迭代中设置
run\u set
操作,并在清除后让主线程通信。在此期间,在不同的阶段,我检查是否设置了
cancel\u set
,以防出现“取消”请求

除了一件事:
nuke.execute()。我曾尝试将其放入
nuke.addBeforeFrameRender
nuke.addAfterFrameRender
回调中,但没有任何效果。我还认为它可能在错误的线程中执行,所以我尝试了
nuke.executeInMainThread(nuke.cancel)
,但没有成功

草案内容如下:

执行(nameOrNode、start、end、incr、views、continueOnError=False) ... 如果Nuke在GUI打开的情况下运行,这将弹出一个进度表。如果用户点击取消按钮,此命令将返回“取消”错误。 如果从Nuke命令行运行Nuke(即Nuke是通过-t开关启动的),则execute()会在运行过程中打印一个文本百分比。 如果用户键入^C,它将中止execute()并返回“取消”错误

所以我尝试用
os.kill(os.getpid(),signal.CTRL\u C\u事件)替换
nuke.cancel()
这实际上停止了渲染,但
execute()
从未返回,因此脚本无法继续

因为
execute()
应该

返回“已取消”错误

我试图从
execute()
os.kill(os.getpid(),signal.CTRL\u C\u事件)
代码中捕获
nuke.cancelederror
异常,但没有抛出

奇怪的是,当我运行此回调时:

def _cancel_callback(self):
        self._is_canceled = True
        os.kill(os.getpid(), signal.CTRL_C_EVENT)
        print "Cancelled"
执行了
打印

我对python相当陌生,所以这可能是noob的错误,但有人知道我可能做错了什么,或者这是API中的错误吗? 或者也许有人能想出一个更好的解决问题的办法-那将是非常感谢

到目前为止,我所看到的摆脱这种情况的唯一方法是简单地关闭worker进程,然后启动一个新的进程,但每次有人想取消一个工作时,这都是一件很糟糕的事情

使用Nuke 9.0v3
完整的源代码可以在PYTHON目录中找到,这是一个很好的问题,我希望知道答案。不是一个答案,但是你可以考虑使用一个渲染排队系统,就像大多数软件一样。它(以及其他类似的工具)的工作方式是每次都通过一个干净的命令行渲染。Nuke命令行渲染器只需几秒钟即可启动,因此可能不值得尝试在渲染之间保持活动状态。是的,对于渲染来说,代价不是很大,但我的任务包括使用指定节点批量创建脚本(主要用于通过高质量分辨率或降噪等处理进行代码转换),而这些可能需要不到一秒钟的时间。如果我找不到可行的解决方案,我只会在需要取消渲染时终止该过程。我建议写信给铸造厂。这听起来确实像一个bug,而且他们通常对这些都很敏感。如果您找到了解决方案,请在此处“回答您自己的问题”,以帮助未来的访问者。
def _cancel_callback(self):
        self._is_canceled = True
        os.kill(os.getpid(), signal.CTRL_C_EVENT)
        print "Cancelled"