flyps 发表于 2021-4-7 15:28:24

关于self实例变量与多线程的报错

本帖最后由 flyps 于 2021-4-7 22:43 编辑

下面有两段代码,第一段是会报错的,第二段是可正常运行的,方法是将self实例变量改为全局变量,问题是假如代码中几十个self实例变量,按方法是要改成几十个全局变量,那么这样是否会降低运行速度,或是严重占用内存。请问是否有更好的方法,谢谢

增加第三段代码,只要tkinter组件,前面是self开头的变量,就会报错。

import multiprocessing as mp
import tkinter as tk

class Test():
    def __init__(self):
      root = tk.Tk()
      frame = tk.Frame(root,height=400,width=400)
      frame.grid(row=0)
      tk.Label(frame,text='1:').grid(row=0,padx=5,pady=5)
      tk.Label(frame,text='2:').grid(row=1,padx=5,pady=5)
      tk.Label(frame,text='3:').grid(row=2,padx=5,pady=5)      
      self.v1 = tk.StringVar()
      self.v2 = tk.StringVar()
      self.v3 = tk.StringVar()
      e1=tk.Entry(frame, textvariable=self.v1,width=3)
      e1.grid(row=0, column=1)
      e1.insert(0,10)
      e2=tk.Entry(frame, textvariable=self.v2,width=3)
      e2.grid(row=1, column=1)
      e2.insert(0,20)
      e3=tk.Entry(frame, textvariable=self.v3,width=3)
      e3.grid(row=2, column=1)
      e3.insert(0,30)
      tk.Button(frame,height=4,width=10,text='执行',command=self.doit).grid(row=3,column=0)
      root.mainloop()
   
    def job(self,q):
      res = 0
      for i in range(1000000):
            res += i + i**2 + i**3
      q.put(res) # queue

    def doit(self):
      q = mp.Queue()
      p1 = mp.Process(target=self.job, args=(q,))
      p2 = mp.Process(target=self.job, args=(q,))
      p1.start()
      p2.start()
      p1.join()
      p2.join()
      res1 = q.get()
      res2 = q.get()
      print('multicore:',res1 + res2)
      print(self.v1.get(),self.v2.get(),self.v3.get())
      

if __name__ == '__main__':
    go = Test()


import multiprocessing as mp
import tkinter as tk

class Test():
    def __init__(self):
      global v1
      global v2
      global v3
      root = tk.Tk()
      frame = tk.Frame(root,height=400,width=400)
      frame.grid(row=0)
      tk.Label(frame,text='1:').grid(row=0,padx=5,pady=5)
      tk.Label(frame,text='2:').grid(row=1,padx=5,pady=5)
      tk.Label(frame,text='3:').grid(row=2,padx=5,pady=5)      
      v1 = tk.StringVar()
      v2 = tk.StringVar()
      v3 = tk.StringVar()
      e1=tk.Entry(frame, textvariable=v1,width=3)
      e1.grid(row=0, column=1)
      e1.insert(0,10)
      e2=tk.Entry(frame, textvariable=v2,width=3)
      e2.grid(row=1, column=1)
      e2.insert(0,20)
      e3=tk.Entry(frame, textvariable=v3,width=3)
      e3.grid(row=2, column=1)
      e3.insert(0,30)
      tk.Button(frame,height=4,width=10,text='执行',command=self.doit).grid(row=3,column=0)
      root.mainloop()
   
    def job(self,q):
      res = 0
      for i in range(1000000):
            res += i + i**2 + i**3
      q.put(res) # queue

    def doit(self):
      q = mp.Queue()
      p1 = mp.Process(target=self.job, args=(q,))
      p2 = mp.Process(target=self.job, args=(q,))
      p1.start()
      p2.start()
      p1.join()
      p2.join()
      res1 = q.get()
      res2 = q.get()
      print('multicore:',res1 + res2)
      print(v1.get(),v2.get(),v3.get())
      

if __name__ == '__main__':
    go = Test()


import multiprocessing as mp
import tkinter as tk

class Test():
    def __init__(self):
      root = tk.Tk()
      frame = tk.Frame(root,height=400,width=400)
      frame.grid(row=0)
      tk.Label(frame,text='1:').grid(row=0,padx=5,pady=5)
      tk.Label(frame,text='2:').grid(row=1,padx=5,pady=5)
      tk.Label(frame,text='3:').grid(row=2,padx=5,pady=5)
      self.l4 = tk.Label(frame,text='4:')
      self.l4.grid(row=3,padx=5,pady=5)
      '''      
      self.v1 = tk.StringVar()
      self.v2 = tk.StringVar()
      self.v3 = tk.StringVar()      
      e1=tk.Entry(frame, textvariable=self.v1,width=3)
      e1.grid(row=0, column=1)
      e1.insert(0,10)
      e2=tk.Entry(frame, textvariable=self.v2,width=3)
      e2.grid(row=1, column=1)
      e2.insert(0,20)
      e3=tk.Entry(frame, textvariable=self.v3,width=3)
      e3.grid(row=2, column=1)
      e3.insert(0,30)
      '''
      tk.Button(frame,height=4,width=10,text='执行',command=self.doit).grid(row=4,column=0)
      root.mainloop()
   
    def job(self,q):
      res = 0
      for i in range(1000000):
            res += i + i**2 + i**3
      q.put(res) # queue

    def doit(self):
      q = mp.Queue()
      p1 = mp.Process(target=self.job, args=(q,))
      p2 = mp.Process(target=self.job, args=(q,))
      p1.start()
      p2.start()
      p1.join()
      p2.join()
      res1 = q.get()
      res2 = q.get()
      print('multicore:',res1 + res2)
      print(self.v1.get(),self.v2.get(),self.v3.get())
      

if __name__ == '__main__':
    go = Test()
    #go.mainloop()
    #go.root.mainloop()

suchocolate 发表于 2021-4-7 16:37:11

我看v1v2v3是窗口数据,不算实例变量,是要全局接入的。

591821661 发表于 2021-4-7 16:49:39

报错信息呢?

flyps 发表于 2021-4-7 20:34:30

suchocolate 发表于 2021-4-7 16:37
我看v1v2v3是窗口数据,不算实例变量,是要全局接入的。

请问若窗口数据数量过多,会不会降低运行速度,或是严重占用内存。如果会,有什么方法可以避免,谢谢

flyps 发表于 2021-4-7 22:32:35

591821661 发表于 2021-4-7 16:49
报错信息呢?

Exception in Tkinter callback
Traceback (most recent call last):
File "C:\users\administrator\appdata\local\programs\python\python38\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
File "f:/Desktop/Code library/filter/03.py", line 37, in doit
    p1.start()
File "C:\users\administrator\appdata\local\programs\python\python38\lib\multiprocessing\process.py", line 121, in start
    self._popen = self._Popen(self)
File "C:\users\administrator\appdata\local\programs\python\python38\lib\multiprocessing\context.py", line 224, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
File "C:\users\administrator\appdata\local\programs\python\python38\lib\multiprocessing\context.py", line 327, in _Popen
    return Popen(process_obj)
File "C:\users\administrator\appdata\local\programs\python\python38\lib\multiprocessing\popen_spawn_win32.py", line 93, in __init__
    reduction.dump(process_obj, to_child)
File "C:\users\administrator\appdata\local\programs\python\python38\lib\multiprocessing\reduction.py", line 60, in dump
    ForkingPickler(file, protocol).dump(obj)
TypeError: cannot pickle '_tkinter.tkapp' object
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\users\administrator\appdata\local\programs\python\python38\lib\multiprocessing\spawn.py", line 116, in spawn_main
    exitcode = _main(fd, parent_sentinel)
File "C:\users\administrator\appdata\local\programs\python\python38\lib\multiprocessing\spawn.py", line 126, in _main
    self = reduction.pickle.load(from_parent)
EOFError: Ran out of input

flyps 发表于 2021-4-8 10:13:39

求解答,谢谢
页: [1]
查看完整版本: 关于self实例变量与多线程的报错