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

时间:2014-07-04 15:57:10

标签: python multithreading

我有一个应用程序从某些网址获得一些结果然后必须根据结果做出决定(即:选择最佳结果并将其显示给用户)。由于我想查看几个网址,这是第一次非常需要多线程。

因此,在一些例子的帮助下,我编写了以下测试代码:

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

这似乎有效,但我在这里真的不安全,因为我几乎没有多线程经验。我总是听到这些术语,如"线程安全"和#34;竞争条件"。

当然我读到了这些东西,但由于这是我第一次使用这样的东西,我的问题是:这样做可以吗?我忽略了任何负面或意外的影响吗?有没有办法改善这个?

欢迎所有提示!

1 个答案:

答案 0 :(得分:7)

当您有多个线程修改同一个对象时,您必须担心竞争条件。在你的情况下,你有这个确切的条件 - 所有线程都在修改theResultList

但是,Python的列表是线程安全的 - read more here。因此,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

在你的情况下,你没有做这样的事情,所以你的代码很好。

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