我有一个应用程序,从一些url获得一些结果,然后必须根据结果做出决定(即:选择最好的结果并将其显示给用户)。因为我想检查几个url,这是第一次,多线程是非常需要的。
因此,在一些示例的帮助下,我编写了以下testcode:import threading
import urllib2
threadsList = []
theResultList = []
def get_url(url):
result = urllib2.urlopen(url).read()
theResultList.append(result[0:10])
theUrls = ['http://google.com', ' http://yahoo.com']
for u in theUrls:
t = threading.Thread(target=get_url, args=(u,))
threadsList.append(t)
t.start()
t.join()
print theResultList
这似乎有效,但我在这里真的不安全,因为我实际上没有多线程的经验。我总是听到像"线程安全"one_answers"竞争条件"这样的术语。
当然我读过这些东西,但因为这是我第一次使用这样的东西,我的问题是:这样做是可以的吗?是否有我忽略的负面或意外影响?有什么方法可以改善这一点吗?欢迎所有提示!
当您有多个线程修改同一个对象时,您必须担心竞争条件。在您的情况下,您有这个确切的条件-所有线程都在修改theResultList
。
然而,Python的列表是线程安全的——在这里了解更多。因此,从多个线程到列表的append
不会以某种方式破坏列表结构——但是,您仍然必须注意保护对单个列表元素的并发修改。例如:
# not thread safe code! - all threads modifying the same element
def get_url(url):
result = urllib2.urlopen(url).read()
#in this example, theResultList is a list of integers
theResultList[0] += 1
在你的例子中,你没有做这样的事情,所以你的代码很好。
注:整数递增不是线程安全的原因是,它实际上是两个操作——一个操作读取值,另一个操作增加值。线程可以在这两个步骤之间被中断(被另一个想要增加相同变量的线程中断)——这意味着当线程最终在第二步中增加时,它可能会增加一个过期的值。