Python3中的线程和队列:input_queue中的哨兵值无法突破while循环
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Python3中的线程和队列:input_queue中的哨兵值无法突破while循环,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3254字,纯文字阅读大概需要5分钟。
内容图文
![Python3中的线程和队列:input_queue中的哨兵值无法突破while循环](/upload/InfoBanner/zyjiaocheng/658/287ce314b4f040b4be9f3467e0cf429d.jpg)
总体概述:
我正在尝试构建一个使用线程从Web抓取信息的应用程序的简单示例.我知道有专用的模块(例如,草率的),但是我想做得更多,以了解和理解线程的工作原理并理解陷阱.另外,我在Python Cookbook(第三版)中看过各种教程(IBM教程和其他教程),关于SO的问题,甚至一些食谱.描述了如何做,但是在使用线程/队列时我仍然挂在某个地方.
首先,我已经阅读了stackoverflow(以及Cookbook),这是浪费threading.Thread子类的浪费,所以我一直在尝试使用Thread(target = …,args =(…))来实现它.大多数教程似乎都使用(较旧的?)子类化方法,采用这种较新的(?)方式可能会使我感到困惑.
其次,在Python Cookbook中,他们提供了将_sentinel值放入工作队列的示例,您的方法会在发现它们时注意并中断该值.我认为这是我遇到麻烦的地方.
最后,我确定我必须进行各种矫kill过正,因此,我将对使事情变得过于复杂的技巧或指针表示赞赏.感谢您的建议.
具体的编码问题和尝试:
我有一个(公司名称,URL)元组的work_queue.我的方法是解析股票代码名称的网址,并将元组(代码名称,公司名称)发送到输出队列.当所有值都用完时,我试图使用一个哨兵来突破该方法:
def grab_ticker_name(input_q, output_q, _sentinel):
'''Function to be threaded later: grabs company ticker from url and sends it to an output queue.'''
while True:
item = input_q.get()
if item is _sentinel:
print("We encountered the sentinel!!")
input_q.put(_sentinel) # See page 492 of Python Cookbook, 3rd Ed.
break
else:
company_name, company_url = item
with urlopen(company_url) as f:
newsoup = BeautifulSoup(f)
if len(newsoup.select('.inlink_chart > a')) > 0:
ticker_name = newsoup.select('.inlink_chart > a')[0].string
output_q.put((ticker_name, company_name))
print("grab_ticker_name grabbed the following: {ticker_name}, {company_name}".format_map(vars()))
input_q.task_done()
我正在填充队列并像这样构建线程(使用打印语句只是为了帮助我了解发生了什么):
def main():
work_queue = queue.Queue()
out_queue = queue.Queue()
_sentinel = object() # This recommendation comes from the *Python Cookbook*
stock_list = StockBuilder()
print("Populating the work_queue now")
for item in stock_list.yield_url():
work_queue.put(item)
work_queue.put(_sentinel)
t1 = threading.Thread(target=grab_ticker_name, args=(work_queue, out_queue, _sentinel))
t2 = threading.Thread(target=grab_ticker_name, args=(work_queue, out_queue, _sentinel))
print("Now we're going to start our threads!")
t1.start() ; t2.start()
print("Now we're going to attempt to join our work queue.")
work_queue.join()
它似乎可以工作,并给我一行又一行的值,但是随后似乎无限循环,直到我必须取消它为止(CTRL C):
...
grab_ticker_name grabbed the following: MRK, Merk
grab_ticker_name grabbed the following: HUM, Humana
We encountered the sentinel!!
grab_ticker_name grabbed the following: WLP, WellPoint
We encountered the sentinel!!
^CTraceback (most recent call last).
...
问题:break表达式为什么没有使函数返回main()?
最后,我还希望能够从out_queue中获取所有数据并将其放入另一个数据结构(列表,字典等)中.
问题2:我知道我可能为此使用带锁的列表,但在这里我也感到困惑,因为我以为我已经读过队列是线程修改可变对象的一种简便方法?
问题2a:假设我使用out_queue,一旦填充了out_queue即可简单地从中获取所有值,是否有一种简单的方法?我想也许我会在work_queue.join()之后将另一个_sentinel放入out_queue中,然后执行另一个while循环,如果不是_sentinel,则对out_queue中的每个项目进行处理?这是天真的方法吗?
谢谢阅读.
解决方法:
问题是您正在加入work_queue,但是work_queue不为空-它中仍然有哨兵.尝试以下方法:
t1.join()
t2.join()
内容总结
以上是互联网集市为您收集整理的Python3中的线程和队列:input_queue中的哨兵值无法突破while循环全部内容,希望文章能够帮你解决Python3中的线程和队列:input_queue中的哨兵值无法突破while循环所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。