创建函数来自另一个类的Process对象[导致错误]



我会尽我所能解释我的问题,请我真的需要你的帮助尤其是对Python多处理器专家来说,因为我喜欢多处理器&我只是一个初学者。

def __handleDoubleClick(self,item):
self.tmx_window.show()
processes = []
#self.tmx_window.fill_table(item.text(),self.language_code,self.xml_filepath.text())
process_ft = Process(target=self.tmx_window.fill_table, args=(item.text(),self.language_code,self.xml_filepath.text()))
processes.append(process_ft)
process_ft.start()

for process in processes:
process.join()

这里有一个函数(__handleDoubleClick(&当你双击PYQT5 GUI中的一个小部件时,这个函数只是做了一些事情,因为你可以在这里看到这行代码self.tmx_window.show(),它显示了我拥有的2ndGUI。如果你对CCD_ 3对象感兴趣,这是它的类,它只是继承了一个类QMainWindow&Ui_TmxWindowUi_TmxWindow来自QT设计器生成的.py文件。

class TmxWindow(QMainWindow,Ui_TmxWindow):
def __init__(self):
super().__init__()
# Set up the user interface from Designer.
self.setupUi(self)

正如你再次看到的,我在这里有一个被调用的函数,这就是代码。

#self.tmx_window.fill_table(item.text(),self.language_code,self.xml_filepath.text())

现在我已经把它注释掉了,我想让它成为一个Process对象,因为我想应用多处理,我需要它在未来与其他进程一起运行。。。现在,正如你所看到的,我已经应用了这个

process_ft = Process(target=self.tmx_window.fill_table, args=(item.text(),self.language_code,self.xml_filepath.text()))
processes.append(process_ft)
process_ft.start()

for process in processes:
process.join()

target的有一个函数,它是self.tmx_window.fill_table,你可以看到的那个函数来自另一个类,我从中创建了一个对象,而你可以看到这个对象是self.tmx_window。现在,在不应用多处理的情况下,一切都很好,因为我正确地调用了函数。。。但当我应用多处理时,会出现这个错误。顺便说一句,你会看到"TmxWindow对象">,并且TmxWindow是我所指的函数属于的类

Traceback (most recent call last):
File "main.py", line 127, in __handleDoubleClick
process_ft.start()
File "C:UsersLENOVO.condaenvsUSA24libmultiprocessingprocess.py", line 121, in start
self._popen = self._Popen(self)
File "C:UsersLENOVO.condaenvsUSA24libmultiprocessingcontext.py", line 224, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
File "C:UsersLENOVO.condaenvsUSA24libmultiprocessingcontext.py", line 327, in _Popen
return Popen(process_obj)
File "C:UsersLENOVO.condaenvsUSA24libmultiprocessingpopen_spawn_win32.py", line 93, in __init__
reduction.dump(process_obj, to_child)
File "C:UsersLENOVO.condaenvsUSA24libmultiprocessingreduction.py", line 60, in dump
ForkingPickler(file, protocol).dump(obj)
TypeError: cannot pickle 'TmxWindow' object
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:UsersLENOVO.condaenvsUSA24libmultiprocessingspawn.py", line 116, in spawn_main
exitcode = _main(fd, parent_sentinel)
File "C:UsersLENOVO.condaenvsUSA24libmultiprocessingspawn.py", line 126, in _main
self = reduction.pickle.load(from_parent)
EOFError: Ran out of input

现在我想尝试做同样的事情,但使用线程,我尝试了这一点,而不是进程和IT工作!我熟悉线程和进程的区别,根据我所读到的内容,线程共享内存,而进程不共享内存,因为它们有自己的内存(如果我错了,请纠正我(,所以这就是为什么我想应用多处理而不是多线程。

所以我担心的问题是我提供的错误。。。以及为什么它适用于Threading tho而不适用于Process。我觉得在MultiProcessing中有一些我还不了解的东西,我只是很好奇。我的意思是,我只是遵循了它,并为Process对象提供了一个函数,而这个函数来自一个不同的类,我用它创建了一个对象的实例。。。有人能帮我吗。非常感谢。

#self.tmx_window.fill_table(item.text(),self.language_code,self.xml_filepath.text())
thread_ft = threading.Thread(target=self.tmx_window.fill_table,args=[item.text(),self.language_code,self.xml_filepath.text()])
threads.append(thread_ft)
thread_ft.start()

需要考虑的重要方面是,除了主Qt线程之外,任何外部线程都不允许访问GUI元素(包括创建新元素(。

当使用多处理时,每个进程都有自己的线程(请注意,我简化了很多(,所以如果使用多处理,基本上也使用不同的线程。此外,python中处理之间的通信是通过pickle完成的(这在Qt对象中不太好用(。

虽然在某些情况下,从其他线程访问UI元素可能会工作,但这通常只是巧合,因为当前的硬件/软件配置允许这些线程同步工作,因为它们可能响应速度很快,并且它们的通信队列不会受到其他事件的影响。但是,再次强调,这主要是一个巧合。我敢肯定,在其他条件下(CPU慢、其他并发进程等(,即使使用线程,您的代码也不会工作。

因此,唯一的安全解决方案使用线程,但只要您需要使用UI元素以任何方式访问,就只能使用Qt的信号和插槽。这意味着你必须使用一个QThread子类(因为它继承了QObject,所以它提供了信号/插槽机制(;处理";并使用您的自定义信号与主Qt线程通信,因此该信号将连接到实际更新您的项目视图的函数。

最新更新