【发布时间】:2015-05-20 15:12:45
【问题描述】:
我用于图形的应用程序具有嵌入式 Python 解释器 - 除了有一些特殊对象之外,它的工作方式与任何其他 Python 解释器完全相同。
基本上我正在尝试使用 Python 下载一堆图像并进行其他网络和磁盘 I/O。如果我在没有多线程的情况下执行此操作,我的应用程序将冻结(即视频停止播放),直到下载完成。
为了解决这个问题,我尝试使用多线程。但是,我无法触及任何主要进程。
我已经写了这段代码。唯一对该程序独特的部分进行了注释。 me.store / me.fetch 基本上是获取全局变量的一种方式。 op('files') 指的是一个全局表。
这是两件事,“在主进程中”,只能以线程安全的方式进行访问。我不确定我的代码是否这样做。
我会感谢任何关于为什么或(为什么不是)此代码是线程安全的以及我如何以线程安全的方式访问全局变量的输入。
我担心的一件事是counter 是如何被许多线程多次获取的。由于它仅在写入文件后才更新,这是否会导致不同线程访问具有相同值的计数器的竞争条件(然后不正确存储递增的值)。或者,如果磁盘写入失败,计数器会发生什么。
from urllib import request
import threading, queue, os
url = 'http://users.dialogfeed.com/en/snippet/dialogfeed-social-wall-twitter-instagram.json?api_key=ac77f8f99310758c70ee9f7a89529023'
imgs = [
'http://search.it.online.fr/jpgs/placeholder-hollywood.jpg.jpg',
'http://www.lpkfusa.com/Images/placeholder.jpg',
'http://bi1x.caltech.edu/2015/_images/embryogenesis_placeholder.jpg'
]
def get_pic(url):
# Fetch image data
data = request.urlopen(url).read()
# This is the part I am concerned about, what if multiple threads fetch the counter before it is updated below
# What happens if the file write fails?
counter = me.fetch('count', 0)
# Download the file
with open(str(counter) + '.jpg', 'wb') as outfile:
outfile.write(data)
file_name = 'file_' + str(counter)
path = os.getcwd() + '\\' + str(counter) + '.jpg'
me.store('count', counter + 1)
return file_name, path
def get_url(q, results):
url = q.get_nowait()
file_name, path = get_pic(url)
results.append([file_name, path])
q.task_done()
def fetch():
# Clear the table
op('files').clear()
results = []
url_q = queue.Queue()
# Simulate getting a JSON feed
print(request.urlopen(url).read().decode('utf-8'))
for img in imgs:
# Add url to queue and start a thread
url_q.put(img)
t = threading.Thread(target=get_url, args=(url_q, results,))
t.start()
# Wait for threads to finish before updating table
url_q.join()
for cell in results:
op('files').appendRow(cell)
return
# Start a thread so that the first http get doesn't block
thread = threading.Thread(target=fetch)
thread.start()
【问题讨论】:
-
看我的回答。但是运行这段代码是完全安全的,因为它所做的只是打印一个回溯,告诉你
offToOn()有四个参数,而不是零。另外为了清楚起见,我强烈建议将所有导入语句移到文件顶部,在任何函数之外。 -
感谢@PaulCornelius,这些参数来自程序,应该被删除。
标签: python multithreading python-3.x