2007年11月13日 星期二 10:10
*我试图用一下的程序实现让一个线程运行5秒钟然后退出,但它没有这么做。* *Python多线程中不能访问模块一级的变量?不解* #-*-coding: utf-8 -*- import time from threading import Thread global timeout timeout = False def count(): i = 0 while(not timeout): print i, timeout time.sleep(0.2) i += 1 def timer(): print timeout time.sleep(5) timeout = True if __name__ == "__main__": tCounter = Thread(target = count) tTimer = Thread(target = timer) tTimer.start() tCounter.start() 输出结果: 0 False Exception in thread Thread-2: Traceback (most recent call last): File "/usr/lib/python2.3/threading.py", line 436, in __bootstrap self.run() File "/usr/lib/python2.3/threading.py", line 416, in run self.__target(*self.__args, **self.__kwargs) File "threadingtest.py", line 17, in timer print timeout UnboundLocalError: local variable 'timeout' referenced before assignment 1 False 2 False 3 False 4 False 5 False 6 False 7 False 8 False 9 False 。。。。。 。。。。。 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://python.cn/pipermail/python-chinese/attachments/20071113/2a9208a1/attachment.html
2007年11月13日 星期二 10:17
On Nov 13, 2007 10:10 AM, Cyril. Liu <terry6394在gmail.com> wrote: > 我试图用一下的程序实现让一个线程运行5秒钟然后退出,但它没有这么做。 > Python多线程中不能访问模块一级的变量?不解 > > #-*-coding: utf-8 -*- > import time > from threading import Thread > global timeout > timeout = False > def count(): > i = 0 > while(not timeout): > print i, timeout > time.sleep(0.2) > i += 1 > def timer(): > print timeout > time.sleep(5) > timeout = True > > if __name__ == "__main__": > tCounter = Thread(target = count) > tTimer = Thread(target = timer) > tTimer.start() > tCounter.start() > > > 输出结果: > > 0 False > Exception in thread Thread-2: > Traceback (most recent call last): > File "/usr/lib/python2.3/threading.py", line 436, in __bootstrap > self.run() > File "/usr/lib/python2.3/threading.py", line 416, in run > self.__target(*self.__args, **self.__kwargs) > File "threadingtest.py", line 17, in timer > print timeout > UnboundLocalError: local variable 'timeout' referenced before assignment > 1 False > 2 False > 3 False > 4 False > 5 False > 6 False > 7 False > 8 False > 9 False > 。。。。。 > 。。。。。 > > 在每个def的下面写global 如: def count(): global timeout -- Best Regards, Leo Jay
2007年11月13日 星期二 11:46
的确每个加上global就好了。 不过我不理解Python的多线程共享变量的机制(或者是不理解模块级变量的机制),难道一定要变成全局变量才行吗? 大家给我解释一下. :D On Nov 13, 2007 10:17 AM, Leo Jay <python.leojay at gmail.com> wrote: > On Nov 13, 2007 10:10 AM, Cyril. Liu <terry6394 at gmail.com> wrote: > > 我试图用一下的程序实现让一个线程运行5秒钟然后退出,但它没有这么做。 > > Python多线程中不能访问模块一级的变量?不解 > > > > #-*-coding: utf-8 -*- > > import time > > from threading import Thread > > global timeout > > timeout = False > > def count(): > > i = 0 > > while(not timeout): > > print i, timeout > > time.sleep(0.2) > > i += 1 > > def timer(): > > print timeout > > time.sleep(5) > > timeout = True > > > > if __name__ == "__main__": > > tCounter = Thread(target = count) > > tTimer = Thread(target = timer) > > tTimer.start() > > tCounter.start() > > > > > > 输出结果: > > > > 0 False > > Exception in thread Thread-2: > > Traceback (most recent call last): > > File "/usr/lib/python2.3/threading.py", line 436, in __bootstrap > > self.run() > > File "/usr/lib/python2.3/threading.py", line 416, in run > > self.__target(*self.__args, **self.__kwargs) > > File "threadingtest.py", line 17, in timer > > print timeout > > UnboundLocalError: local variable 'timeout' referenced before assignment > > 1 False > > 2 False > > 3 False > > 4 False > > 5 False > > 6 False > > 7 False > > 8 False > > 9 False > > 。。。。。 > > 。。。。。 > > > > > > 在每个def的下面写global > 如: > def count(): > global timeout > > > > > -- > Best Regards, > Leo Jay > _______________________________________________ > python-chinese > Post: send python-chinese at lists.python.cn > Subscribe: send subscribe to python-chinese-request at lists.python.cn > Unsubscribe: send unsubscribe to python-chinese-request at lists.python.cn > Detail Info: http://python.cn/mailman/listinfo/python-chinese -------------- next part -------------- An HTML attachment was scrubbed... URL: http://python.cn/pipermail/python-chinese/attachments/20071113/42e83361/attachment.htm
2007年11月13日 星期二 12:10
On Nov 13, 2007 11:46 AM, Cyril. Liu <terry6394在gmail.com> wrote: > 的确每个加上global就好了。 > 不过我不理解Python的多线程共享变量的机制(或者是不理解模块级变量的机制),难道一定要变成全局变量才行吗? > 大家给我解释一下. :D > 这个不是多线程共享变量的机制的问题,是怎么使用全局变量的问题。呵呵。 一个全局变量,你要在某个函数中对它进行赋值的时候,一定要在函数的一开头用 global注明你要使用的是一个全局变量。就像你那个timer一样。是一定要写的。 不过,如果你不修改,只要读它的数据的话,是可以不写的,像那个count函数一样。 python在执行到使用timeout的地方时,在函数里没找到timeout的定义,就会自动到 global里去找。 不过,我个人的习惯是,如果要使用全局的变量的时候,都加上一个global的声明, 以防止出错。 -- Best Regards, Leo Jay
2007年11月13日 星期二 12:11
每个线程的函数都是独立调用的, 另外,注意有些变量的操作并不是原子的, 去看看 Queue 等线程安全的实现 在 07-11-13,Cyril. Liu<terry6394 at gmail.com> 写道: > 的确每个加上global就好了。 > 不过我不理解Python的多线程共享变量的机制(或者是不理解模块级变量的机制),难道一定要变成全局变量才行吗? > 大家给我解释一下. :D >
2007年11月13日 星期二 16:44
嗯,我也是这个习惯,结果某次去面试时被鄙视了一下,对方说:这个语句多余。 在 07-11-13,Leo Jay<python.leojay在gmail.com> 写道: > On Nov 13, 2007 11:46 AM, Cyril. Liu <terry6394在gmail.com> wrote: > > 的确每个加上global就好了。 > > 不过我不理解Python的多线程共享变量的机制(或者是不理解模块级变量的机制),难道一定要变成全局变量才行吗? > > 大家给我解释一下. :D > > > > 这个不是多线程共享变量的机制的问题,是怎么使用全局变量的问题。呵呵。 > > 一个全局变量,你要在某个函数中对它进行赋值的时候,一定要在函数的一开头用 > global注明你要使用的是一个全局变量。就像你那个timer一样。是一定要写的。 > > 不过,如果你不修改,只要读它的数据的话,是可以不写的,像那个count函数一样。 > python在执行到使用timeout的地方时,在函数里没找到timeout的定义,就会自动到 > global里去找。 > > 不过,我个人的习惯是,如果要使用全局的变量的时候,都加上一个global的声明, > 以防止出错。 > > -- > Best Regards, > Leo Jay > _______________________________________________ > python-chinese > Post: send python-chinese在lists.python.cn > Subscribe: send subscribe to python-chinese-request在lists.python.cn > Unsubscribe: send unsubscribe to python-chinese-request在lists.python.cn > Detail Info: http://python.cn/mailman/listinfo/python-chinese
2007年11月14日 星期三 17:57
除去global的问题,以多线程环境来说,这个程序其实是不安全的。 对非只读(mutable)共享变量的任何非原子操作序列(包括需要维护一致性的相关操作,可以用"事务"来理解)都需要锁机制才能保证同步。 以这里为例,timeout显然是一个mutable的共享变量,但: *print i, timeout* 这一句就不是原子操作,可能会print到一半的时候线程切换,然后timeout的值被改变,这样就破坏了语义上的一致性。 关于线程同步问题,这篇文章讲解得比较完整: http://effbot.org/zone/thread-synchronization.htm On Nov 13, 2007 11:46 AM, Cyril. Liu <terry6394 at gmail.com> wrote: > 的确每个加上global就好了。 > 不过我不理解Python的多线程共享变量的机制(或者是不理解模块级变量的机制),难道一定要变成全局变量才行吗? > 大家给我解释一下. :D > > > On Nov 13, 2007 10:17 AM, Leo Jay <python.leojay at gmail.com > wrote: > > > On Nov 13, 2007 10:10 AM, Cyril. Liu < terry6394 at gmail.com> wrote: > > > 我试图用一下的程序实现让一个线程运行5秒钟然后退出,但它没有这么做。 > > > Python多线程中不能访问模块一级的变量?不解 > > > > > > #-*-coding: utf-8 -*- > > > import time > > > from threading import Thread > > > global timeout > > > timeout = False > > > def count(): > > > i = 0 > > > while(not timeout): > > > print i, timeout > > > time.sleep(0.2) > > > i += 1 > > > def timer(): > > > print timeout > > > time.sleep(5) > > > timeout = True > > > > > > if __name__ == "__main__": > > > tCounter = Thread(target = count) > > > tTimer = Thread(target = timer) > > > tTimer.start() > > > tCounter.start() > > > > > > > > > 输出结果: > > > > > > 0 False > > > Exception in thread Thread-2: > > > Traceback (most recent call last): > > > File "/usr/lib/python2.3/threading.py", line 436, in __bootstrap > > > self.run() > > > File "/usr/lib/python2.3/threading.py", line 416, in run > > > self.__target(*self.__args, **self.__kwargs) > > > File "threadingtest.py", line 17, in timer > > > print timeout > > > UnboundLocalError: local variable 'timeout' referenced before > > assignment > > > 1 False > > > 2 False > > > 3 False > > > 4 False > > > 5 False > > > 6 False > > > 7 False > > > 8 False > > > 9 False > > > 。。。。。 > > > 。。。。。 > > > > > > > > > > 在每个def的下面写global > > 如: > > def count(): > > global timeout > > > > > > > > > > -- > > Best Regards, > > Leo Jay > > _______________________________________________ > > python-chinese > > Post: send python-chinese at lists.python.cn > > Subscribe: send subscribe to python-chinese-request at lists.python.cn > > Unsubscribe: send unsubscribe to python-chinese-request at lists.python.cn > > Detail Info: http://python.cn/mailman/listinfo/python-chinese > > > > _______________________________________________ > python-chinese > Post: send python-chinese at lists.python.cn > Subscribe: send subscribe to python-chinese-request at lists.python.cn > Unsubscribe: send unsubscribe to python-chinese-request at lists.python.cn > Detail Info: http://python.cn/mailman/listinfo/python-chinese > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://python.cn/pipermail/python-chinese/attachments/20071114/a6384040/attachment-0001.html
2007年11月14日 星期三 18:12
所以说请参考 Queue 等线程安全的数据结构 在 07-11-14,swordsp<sparas2006 at gmail.com> 写道: > 除去global的问题,以多线程环境来说,这个程序其实是不安全的。
2007年11月14日 星期三 19:14
File "threadingtest.py", line 17, in timer print timeout UnboundLocalError: local variable 'timeout' referenced before assignment 这段错误信息来看,print我也只是对timeout变量做一个读操作而已,按你的说法,"只要读它的数据的话,是可以不写" 这个地方是不会报错的啊。 另外从报错的信息来看 "local variable 'timeout' referenced before assignment" 系统认为timeout没有定义。对于被多线程执行的函数来说是不在模块这个作用域内的呢?因为假设timer这个方法是模块内不通过threading来执行,是不会有任何问题的。 不知道可否这样理解Python解释器在通过threading.Thread ()创建线程对象的时候只是把timer方法引用到了Thread类中,没有做其他的处理。 On Nov 13, 2007 12:10 PM, Leo Jay <python.leojay at gmail.com> wrote: > On Nov 13, 2007 11:46 AM, Cyril. Liu <terry6394 at gmail.com> wrote: > > 的确每个加上global就好了。 > > 不过我不理解Python的多线程共享变量的机制(或者是不理解模块级变量的机制),难道一定要变成全局变量才行吗? > > 大家给我解释一下. :D > > > > 这个不是多线程共享变量的机制的问题,是怎么使用全局变量的问题。呵呵。 > > 一个全局变量,你要在某个函数中对它进行赋值的时候,一定要在函数的一开头用 > global注明你要使用的是一个全局变量。就像你那个timer一样。是一定要写的。 > > 不过,如果你不修改,只要读它的数据的话,是可以不写的,像那个count函数一样。 > python在执行到使用timeout的地方时,在函数里没找到timeout的定义,就会自动到 > global里去找。 > > 不过,我个人的习惯是,如果要使用全局的变量的时候,都加上一个global的声明, > 以防止出错。 > > -- > Best Regards, > Leo Jay > _______________________________________________ > python-chinese > Post: send python-chinese at lists.python.cn > Subscribe: send subscribe to python-chinese-request at lists.python.cn > Unsubscribe: send unsubscribe to python-chinese-request at lists.python.cn > Detail Info: http://python.cn/mailman/listinfo/python-chinese > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://python.cn/pipermail/python-chinese/attachments/20071114/a1dd13c6/attachment.htm
2007年11月14日 星期三 20:50
On Nov 14, 2007 7:14 PM, Cyril. Liu <terry6394在gmail.com> wrote: > File "threadingtest.py", line 17, in timer > print timeout > UnboundLocalError: local variable 'timeout' referenced before assignment > > 这段错误信息来看,print我也只是对timeout变量做一个读操作而已,按你的说法,"只要读它的数据的话,是可以不写" 这个地方是不会报错的啊。 这里是在读,可是,你下面有写的操作啊。就是timeout = True那句。 不信你把这句去掉看看。 > 另外从报错的信息来看 "local variable 'timeout' referenced before assignment" > 系统认为timeout没有定义。对于被多线程执行的函数来说是不在模块这个作用域内的呢?因为假设timer这个方法是模块内不通过threading来执行,是不会有任何问题的。 > 不知道可否这样理解Python解释器在通过threading.Thread()创建线程对象的时候只是把timer方法引用到了Thread类中,没有做其他的处理。 > > 你这种说法不对,在同一个进程中的全局变量是谁都可以访问的。跟线程没关系。 -- Best Regards, Leo Jay
2007年11月15日 星期四 13:24
doudou doudou,您好! 我的理解是: 如果要对一个全局变量赋值,那么应该用 global声明一下,否则就不是必要的 刚开始学python,不知道这样对否? ======= 2007-11-13 16:45:35 您在来信中写道:======= >嗯,我也是这个习惯,结果某次去面试时被鄙视了一下,对方说:这个语句多余。 > >在 07-11-13,Leo Jay<python.leojay在gmail.com> 写道: >> On Nov 13, 2007 11:46 AM, Cyril. Liu <terry6394在gmail.com> wrote: >> > 的确每个加上global就好了。 >> > 不过我不理解Python的多线程共享变量的机制(或者是不理解模块级变量的机制),难道一定要变成全局变量才行吗? >> > 大家给我解释一下. :D >> > >> >> 这个不是多线程共享变量的机制的问题,是怎么使用全局变量的问题。呵呵。 >> >> 一个全局变量,你要在某个函数中对它进行赋值的时候,一定要在函数的一开头用 >> global注明你要使用的是一个全局变量。就像你那个timer一样。是一定要写的。 >> >> 不过,如果你不修改,只要读它的数据的话,是可以不写的,像那个count函数一样。 >> python在执行到使用timeout的地方时,在函数里没找到timeout的定义,就会自动到 >> global里去找。 >> >> 不过,我个人的习惯是,如果要使用全局的变量的时候,都加上一个global的声明, >> 以防止出错。 >> >> -- >> Best Regards, >> Leo Jay >> _______________________________________________ >> python-chinese >> Post: send python-chinese在lists.python.cn >> Subscribe: send subscribe to python-chinese-request在lists.python.cn >> Unsubscribe: send unsubscribe to python-chinese-request在lists.python.cn >> Detail Info: http://python.cn/mailman/listinfo/python-chinese >_______________________________________________ >python-chinese >Post: send python-chinese在lists.python.cn >Subscribe: send subscribe to python-chinese-request在lists.python.cn >Unsubscribe: send unsubscribe to python-chinese-request在lists.python.cn >Detail Info: http://python.cn/mailman/listinfo/python-chinese = = = = = = = = = = = = = = = = = = = = 致 礼! 李昆仑 jackyboy在163.com 2007-11-15
2007年11月18日 星期日 15:20
呵呵,很对的
Zeuux © 2025
京ICP备05028076号