鱼C论坛

 找回密码
 立即注册
查看: 2665|回复: 5

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

[复制链接]
发表于 2021-4-7 15:28:24 | 显示全部楼层 |阅读模式
60鱼币
本帖最后由 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()

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-4-7 16:37:11 | 显示全部楼层
我看v1v2v3是窗口数据,不算实例变量,是要全局接入的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-4-7 16:49:39 From FishC Mobile | 显示全部楼层
报错信息呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-4-7 20:34:30 | 显示全部楼层
suchocolate 发表于 2021-4-7 16:37
我看v1v2v3是窗口数据,不算实例变量,是要全局接入的。

请问若窗口数据数量过多,会不会降低运行速度,或是严重占用内存。如果会,有什么方法可以避免,谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-4-7 22:32:35 | 显示全部楼层

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
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-4-8 10:13:39 | 显示全部楼层
求解答,谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-22 16:36

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表