星期日, 七月 29, 2007

python variables sharing between threads

python list pop in loop 中说明了在循环中使用 pop 的问题,同时说明的多进程的情况。因为在 mirrod/fs_mirror 项目中必须使用共享 WatchManager,所以可以考虑先看看线程的情况。
#!/usr/bin/env python
# -*- encoding: utf-8 -*-

import sys
import threading
import time
import random

L = [ chr(i+97) for i in range(26) ]
print L

idx = 20

def run_thread():
# print "index: %d, %s" % (idx, L[idx])
for x in L:
i = L.index(x)
# print "thread: %d, %s" % (i, x)
time.sleep(1)
if i == idx:
for j in range(int(random.random() * 10000)): sys.stdout.write("*")
print
print "thread: %d, %s" % (i, x)
try:
i = L.index(x)
except ValueError:
print "index: %d, %s" % (i, L[i])
# Has been pop out
if i == idx + 1:
print "index + 1: %d, %s" % (i, L[i])
print "Child thread end"
# print "Child List:", L

srv = threading.Thread(target=run_thread, name='child')
srv.setDaemon(1)
srv.start()
# L.extend(['x', 'y', 'z'])
# time.sleep(3)
for x in L:
i = L.index(x)
# print "main: %d, %s" % (i, x)
time.sleep(1)
if i == idx:
for j in range(int(random.random() * 10000)): sys.stdout.write("-")
print
print "main: %d, %s" % (i, x)
print "pop %d, %s" % (i, L[i])
L.pop(i)
print "Main thread end"
# print "Main List:", L
srv.join()
父线程会从列表中取出 L[20],子线程在 L[20] 出打印结果,看输出结果:
sh$ python mirrord_4_sharing_thread.py
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
------...
main: 20, u
pop 20, u
******...
thread: 20, u
index: 20, v
index + 1: 21, w
Main thread end
Child thread end
可以看到,在 main thread 取出 20, 'u' 的同时,child thread 开始认为 20 是 'u',但马上由变成了 20, 'v',因为 20 在 for 中已经走过以此,因此在下一个循环中将直接进入 21,这是 'v' 就被 child thread 忽略了!

这里,必须考虑 Lock 的问题!

没有评论: