Python线程的这种用法安全/好吗?



我有一个应用程序,从一些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

在你的例子中,你没有做这样的事情,所以你的代码很好。

注:整数递增不是线程安全的原因是,它实际上是两个操作——一个操作读取值,另一个操作增加值。线程可以在这两个步骤之间被中断(被另一个想要增加相同变量的线程中断)——这意味着当线程最终在第二步中增加时,它可能会增加一个过期的值。

最新更新