我正在尝试在一个线程中运行Virtualbox。在while循环的第二次迭代期间,th变量被重新分配,应用程序崩溃并产生Win32异常。这似乎是由vbox和session的发布引起的。我的问题是如何手动正确释放它们?
Win32 exception occurred releasing IUnknown at 0x035e40b8
Win32 exception occurred releasing IUnknown at 0x04babcb0
我的应用程序的基础知识(来自pyvbox和virtualbox sdk的virtualbox)
import virtualbox
import threading
import time
class ThreadExecutor(threading.Thread):
def __init__(self):
self.vbox = None
self.session = None
self.vm = None
super().__init__()
def run(self):
self.vbox = virtualbox.VirtualBox()
self.session = virtualbox.Session()
self.vm = self.vbox.find_machine("Ubuntu")
self.vm.launch_vm_process(self.session, 'gui', '')
time.sleep(30)
if int(self.session.state) == 1:
print('Boot failed!')
return
else:
print('Powering down')
self.session.console.power_down()
print('Operation completed')
return
if __name__ == '__main__':
while True:
print('Input')
if input():
th = ThreadExecutor()
th.start()
print('Thread started')
time.sleep(5)
while th.isAlive():
print('App running')
time.sleep(5)
print('Execution finished')
要释放会话可靠,您应该使用try / except / finally结构,如下所示:
try:
#Your code
except:
print("something unexpected happend")
finally:
self.session.console.power_down()
我修改了代码(没有运行它):
为了工作和调试问题(无意修复它 - 至少在此阶段不是这样)。
code.朋友:
#!/usr/bin/env python3
import sys
import virtualbox
import threading
import time
DEFAULT_DEBUG_MSG_INDENT = " "
def debug(text, indent_count, indent=DEFAULT_DEBUG_MSG_INDENT, leading_eoln_count=0):
print("{:s}{:s}[TID: {:06d}]: {:s}".format("\n" * leading_eoln_count, indent * indent_count, threading.get_ident(), text))
class ThreadExecutor(threading.Thread):
def __init__(self):
super().__init__()
self.vbox = virtualbox.VirtualBox()
self.session = virtualbox.Session()
if not self.vbox or not self.session:
raise RuntimeError("virtualbox initialization failed")
self.vm = self.vbox.find_machine("Ubuntu")
if not self.vm:
raise ValueError("VM not found")
def run(self):
start_wait_time = 15
debug("Starting VM...", 1)
self.vm.launch_vm_process(self.session, "gui", "")
debug("Sleeping {:d} secs...".format(start_wait_time), 1)
time.sleep(start_wait_time)
if int(self.session.state) == 1:
debug("Boot failed!", 1)
return
else:
debug("Powering down", 1)
self.session.console.power_down()
debug("Operation completed", 1)
def run(threaded=True):
debug("RUNNING with{:s} threads".format("" if threaded else "out"), 0, leading_eoln_count=1)
sleep_time = 5
while input("{:s}Press ANY key followed by ENTER to continue, ENTER ONLY to queet: ".format(DEFAULT_DEBUG_MSG_INDENT)):
th = ThreadExecutor()
if threaded:
debug("Starting thread...", 0)
th.start()
debug("Thread started", 1)
time.sleep(sleep_time)
while th.isAlive():
debug("App running", 1)
time.sleep(sleep_time)
else:
debug("Running...", 0)
th.run()
debug("Execution finished", 1)
debug("Done", 0)
def main():
run(threaded=False)
run()
if __name__ == "__main__":
print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
main()
它工作了!!!
输出:
(py35x64_test) e:\Work\Dev\StackOverflow\q051136288>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" code.py Python 3.5.4 (v3.5.4:3f56838, Aug 8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] on win32 [TID: 036256]: RUNNING without threads Press ANY key followed by ENTER to continue, ENTER ONLY to queet: a [TID: 036256]: Running... [TID: 036256]: Starting VM... [TID: 036256]: Sleeping 15 secs... [TID: 036256]: Powering down [TID: 036256]: Operation completed [TID: 036256]: Execution finished Press ANY key followed by ENTER to continue, ENTER ONLY to queet: a [TID: 036256]: Running... [TID: 036256]: Starting VM... [TID: 036256]: Sleeping 15 secs... [TID: 036256]: Powering down [TID: 036256]: Operation completed [TID: 036256]: Execution finished Press ANY key followed by ENTER to continue, ENTER ONLY to queet: [TID: 036256]: Done [TID: 036256]: RUNNING with threads Press ANY key followed by ENTER to continue, ENTER ONLY to queet: a [TID: 036256]: Starting thread... [TID: 038520]: Starting VM... [TID: 036256]: Thread started [TID: 038520]: Sleeping 15 secs... [TID: 036256]: App running [TID: 036256]: App running [TID: 036256]: App running [TID: 038520]: Powering down [TID: 038520]: Operation completed [TID: 036256]: Execution finished Press ANY key followed by ENTER to continue, ENTER ONLY to queet: a [TID: 036256]: Starting thread... [TID: 028884]: Starting VM... [TID: 036256]: Thread started [TID: 028884]: Sleeping 15 secs... [TID: 036256]: App running [TID: 036256]: App running [TID: 036256]: App running [TID: 028884]: Powering down [TID: 028884]: Operation completed [TID: 036256]: Execution finished Press ANY key followed by ENTER to continue, ENTER ONLY to queet: [TID: 036256]: Done
原始代码投掷(仅相关部分):
pywintypes.com_error: (-2147221008, 'CoInitialize has not been called.', None, None)
我怀疑在初始化程序中移动virualbox init的东西可能是行为改变的原因(虽然正如我所说,我只是移动了代码,因为我认为初始化程序是正确的位置) - 这是正确的:将代码移回run再次触发异常。
在对virtualbox和vboxapi代码进行简要检查之后,我认为它与CoInitializeEx发生的地方(线程)有关,但我不能指责它。
我还尝试在主块中手动调用该函数(pythoncom.CoInitializeEx(0)
),但单独的import pythoncom
触发了在第一次迭代中出现的异常。