首页 / PYTHON / Python如何停止线程操作
Python如何停止线程操作
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Python如何停止线程操作,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3842字,纯文字阅读大概需要6分钟。
内容图文
我想知道如何使用CTRL C或类似命令在控制台中停止程序.
问题是我的程序中有两个线程.线程一爬网并提取一些数据,线程二以可读格式为用户显示此数据.这两部分共享相同的数据库.我这样运行它们:
from threading import Thread
import ResultsPresenter
def runSpider():
Thread(target=initSpider).start()
Thread(target=ResultsPresenter.runPresenter).start()
if __name__ == "__main__":
runSpider()
我怎样才能做到这一点?
好的,所以我创建了自己的线程类:
import threading
class MyThread(threading.Thread):
"""Thread class with a stop() method. The thread itself has to check
regularly for the stopped() condition."""
def __init__(self):
super(MyThread, self).__init__()
self._stop = threading.Event()
def stop(self):
self._stop.set()
def stopped(self):
return self._stop.isSet()
确定,所以我将在此处发布resultPresenter和搜寻器的摘要.
这是resultPresenter的代码:
# configuration
DEBUG = False
DATABASE = database.__path__[0] + '/database.db'
app = Flask(__name__)
app.config.from_object(__name__)
app.config.from_envvar('CRAWLER_SETTINGS', silent=True)
def runPresenter():
url = "http://127.0.0.1:5000"
webbrowser.open_new(url)
app.run()
这里我还省略了另外两个方法-其中一个连接数据库,第二个方法加载html模板以显示结果.我重复此操作,直到满足条件或用户停止程序(我要实现的目的)为止.还有另外两种方法-一种是从命令行获取get的初始链接,另一种是使用有效参数-如果参数无效,我将不会运行crawl()方法.
这是crawler的简短版本:
def crawl(initialLink, maxDepth):
#here I am setting initial values, lists etc
while not(depth >= maxDepth or len(pagesToCrawl) <= 0):
#this is the main loop that stops when certain depth is
#reached or there is nothing to crawl
#Here I am popping urls from url queue, parse them and
#insert interesting data into the database
parser.close()
sock.close()
dataManager.closeConnection()
这是在线程中启动这些模块的初始化文件:
import ResultsPresenter, MyThread, time, threading
def runSpider():
MyThread.MyThread(target=initSpider).start()
MyThread.MyThread(target=ResultsPresenter.runPresenter).start()
def initSpider():
import Crawler
import database.__init__
import schemas.__init__
import static.__init__
import templates.__init__
link, maxDepth = Crawler.getInitialLink()
if link:
Crawler.crawl(link, maxDepth)
killall = False
if __name__ == "__main__":
global killall
runSpider()
while True:
try:
time.sleep(1)
except:
for thread in threading.enumerate():
thread.stop()
killall = True
raise
解决方法:
杀死线程不是一个好主意,因为(正如您已经说过的那样)线程可能正在对数据库执行一些关键操作.因此,您可以定义全局标志,该标志将向线程发出信号,告知它们应完成其正在执行的操作并退出.
killall = False
import time
if __name__ == "__main__":
global killall
runSpider()
while True:
try:
time.sleep(1)
except:
/* send a signal to threads, for example: */
killall = True
raise
在每个线程中,您都在类似的循环中检查killall变量是否设置为True.如果关闭,则所有活动并退出线程.
编辑
首先:异常非常明显.您正在将目标参数传递给__init__,但没有在__init__中声明它.像这样做:
class MyThread(threading.Thread):
def __init__(self, *args, **kwargs):
super(MyThread, self).__init__(*args, **kwargs)
self._stop = threading.Event()
其次:您没有使用我的代码.如我所说:设置标志并在线程中检查它.当我说“线程”时,我实际上是指处理程序,即ResultsPresenter.runPresenter或initSpide.向我们展示其中之一的代码,我将尝试向您展示如何处理停止.
编辑2
假定爬网函数的代码在同一文件中(如果不在同一文件中,则必须导入killall变量),可以执行以下操作
def crawl(initialLink, maxDepth):
global killall
# Initialization.
while not killall and not(depth >= maxDepth or len(pagesToCrawl) <= 0):
# note the killall variable in while loop!
# the other code
parser.close()
sock.close()
dataManager.closeConnection()
所以基本上您只是说:“嘿,线程,立即退出循环!”.您可以选择从字面上中断循环:
while not(depth >= maxDepth or len(pagesToCrawl) <= 0):
# some code
if killall:
break
当然,退出仍然需要一些时间(必须完成循环并关闭解析器,套接字等),但是应该安全退出.至少是这个主意.
内容总结
以上是互联网集市为您收集整理的Python如何停止线程操作全部内容,希望文章能够帮你解决Python如何停止线程操作所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。