Python、C# 和 Ruby 中的线程比较
我觉得我发现了C#和Ruby能做到的事情,但Python却做不到。
在C#中:
for (var i = 0; i < 100; i++)
new Thread(() => { Console.Write(i+" "); }).Start();
Console.ReadLine();
在Ruby中:
for i in 0...100
Thread.start{
print i + ''
}
end
gets
有没有什么想法?你能把上面的代码用Python重写一下吗?输出结果应该和C#和Ruby类似:有重复的数字。
编辑
输出结果是打印100次,包含重复的数字。如果你定义一个类或者新方法,你只会得到100次打印,没有重复的数字。我知道得到重复的数字没有意义,我只是想用Python实现和C#、Ruby一样的效果。
C#的示例输出:
3 3 3 3 5 7 8 8 10 10 12 12 13 14 17 17 17 18 20 20 22 23 24 24 25 28 28 29 29 3
1 31 33 33 34 36 38 38 38 41 41 41 42 44 45 45 46 49 49 50 50 52 52 55 56 56 56
58 59 59 60 61 64 64 64 66 66 67 68 69 72 72 72 73 74 76 76 78 78 81 81 82 83 84
84 86 86 87 89 89 90 93 94 94 95 95 97 97 99 99 100
Ruby的示例输出:
99999999999999999999999999999999999999999999999999999999999999999999999999999999
99999999999999999999999999999999999999999999999999999999999999999999999999999999
9999999999999999999999999999999999999999
我为什么想要重复的数字:
C#和Ruby代码的输出有重复的数字。这是因为主线程在改变变量i的值,所以一些子线程可能会打印相同的数字。主线程和子线程都在引用同一个变量i。有时候这很有用:主线程改变了变量,所有子线程都能获取到更新后的变量。
但是我们该如何在Python中做到这一点呢?
4 个回答
2
在Python中:
import threading
def action(arg):
print arg
for i in range(100):
threading.Thread(target=action, args=(i,)).start()
2
其实你是可以这样做的:
>>> import threading
>>> def target():
... print 123
...
>>> threading.Thread(target=target).start()
123
你的例子可以写成这样:
>>> def target(i):
... print i
...
>>> for i in xrange(100):
... threading.Thread(target=target, args=(i,)).start()
...
0
1
2
3
<and so on>
1
如果你希望不同的线程有时能看到相同的 i
的值,那么你需要传入一个可以改变的对象,并对它进行修改:
import threading
def action(arg):
print arg[0],
mutable = [0]
for i in range(100):
mutable[0] = i
threading.Thread(target=action, args=(mutable,)).start()
这和你是否为线程定义一个单独的类没有关系,关键在于你是如何在线程之间共享这个值的。使用全局变量也会以同样的方式搞乱你的线程。
示例输出:
0 1 2 3 5 5 6 8 9 9 11 11 12 1314 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 3
0 31 32 33 34 35 36 37 39 39 40 41 43 44 44 45 46 47 48 49 50 51 53 53 54 55 56
5758 59 60 61 62 64 65 6666 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 8
4 85 86 87 89 90 90 92 93 93 94 95 96 9898 99