多线程:为什么生成器不是线程安全的?在线程之间共享时会发生什么?

编程入门 行业动态 更新时间:2024-10-28 00:27:21
本文介绍了多线程:为什么生成器不是线程安全的?在线程之间共享时会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在阅读这个问题,它询问生成器是否是线程安全的,还有一个回答说:

它不是线程安全的;同时通话可能会交错,并与 局部变量.

另一个答案显示,您可以使用锁来确保一次只有一个线程使用生成器. /p>

我是多线程新手.谁能设计一个例子来说明当您使用无锁发生器时到底发生了什么?

例如,如果我这样做,似乎没有任何问题:

import threading def generator(): for i in data: yield i class CountThread(threading.Thread): def __init__(self, name): threading.Thread.__init__(self) self.name = name def run(self): for i in gen(): print '{0} {1}'.format(self.name, i) data = [i for i in xrange(100)] gen = generator() a = CountThread('a') b = CountThread('b') a.start() b.start()

解决方案

运行此示例.

您将看到10,000个数字将在线程之间共享".在两个线程中都不会看到10000个数字.

实际上最有可能一个线程看到所有数字.

import threading class CountThread(threading.Thread): def __init__(self, gen): threading.Thread.__init__(self) self.gen = gen self.numbers_seen = 0 def run(self): for i in self.gen: self.numbers_seen += 1 def generator(data): for _ in data: yield data gen = generator(xrange(10000)) a = CountThread(gen) b = CountThread(gen) a.start() b.start() a.join() b.join() print "Numbers seen in a", a.numbers_seen print "Numbers seen in b", b.numbers_seen

实际上,如果发生Python在执行期间切换线程的情况(只是使用一个大于10000的值,例如10000000),则会出现异常:

Exception in thread Thread-2: Traceback (most recent call last): File "/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 808, in __bootstrap_inner self.run() File "test.py", line 10, in run for i in self.gen: ValueError: generator already executing

I'm reading this question which asks if generators are thread-safe, and one answer said:

It's not thread-safe; simultaneous calls may interleave, and mess with the local variables.

Another answer shows that you can use a lock to ensure that only one thread uses the generator at a time.

I'm new to multithreading. Can anyone devise an example to show what exactly happens when you use the generator without lock?

For example, it doesn't seem to have any problems if I do this:

import threading def generator(): for i in data: yield i class CountThread(threading.Thread): def __init__(self, name): threading.Thread.__init__(self) self.name = name def run(self): for i in gen(): print '{0} {1}'.format(self.name, i) data = [i for i in xrange(100)] gen = generator() a = CountThread('a') b = CountThread('b') a.start() b.start()

解决方案

Run this example.

You'll see that the 10 000 numbers will be "shared" across threads. You won't see the 10 000 numbers in both threads.

It's actually most likely that one thread will see all the numbers.

import threading class CountThread(threading.Thread): def __init__(self, gen): threading.Thread.__init__(self) self.gen = gen self.numbers_seen = 0 def run(self): for i in self.gen: self.numbers_seen += 1 def generator(data): for _ in data: yield data gen = generator(xrange(10000)) a = CountThread(gen) b = CountThread(gen) a.start() b.start() a.join() b.join() print "Numbers seen in a", a.numbers_seen print "Numbers seen in b", b.numbers_seen

Actually, if it happens that Python switches threads during execution (just use a higher value than 10000, e.g. 10000000), you'll get an exception:

Exception in thread Thread-2: Traceback (most recent call last): File "/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 808, in __bootstrap_inner self.run() File "test.py", line 10, in run for i in self.gen: ValueError: generator already executing

更多推荐

多线程:为什么生成器不是线程安全的?在线程之间共享时会发生什么?

本文发布于:2023-08-04 23:04:41,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1300376.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:线程   生成器   时会   多线程   发生

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!