简体   繁体   English

Python,向线程内的阻塞循环发送停止通知

[英]Python, send a stop notification to a blocking loop within a thread

I've read many answers, however I have not found a proper solution. 我已经阅读了许多答案,但是我没有找到合适的解决方案。

The problem, I'm reading mixed/replace HTTP streams that will not expire or end by default. 问题是,我正在读取混合/替换的HTTP流 ,这些默认不会过期或结束。

You can try it by yourself using curl: 您可以使用curl自己尝试:

curl http://agent.mtconnect.org/sample\?interval\=0

So, now I'm using Python threads and requests to read data from multiple streams. 因此,现在我正在使用Python线程和请求从多个流中读取数据。

import requests
import uuid
from threading import Thread

tasks = ['http://agent.mtconnect.org/sample?interval=5000',
         'http://agent.mtconnect.org/sample?interval=10000']
thread_id = []


def http_handler(thread_id, url, flag):
    print 'Starting task %s' % thread_id
    try:
        requests_stream = requests.get(url, stream=True, timeout=2)
        for line in requests_stream.iter_lines():
            if line:
                print line
            if flag and line.endswith('</MTConnectStreams>'):
                # Wait until XML message end is reached to receive the full message
                break

    except requests.exceptions.RequestException as e:
        print('error: ', e)

    except BaseException as e:
        print e


if __name__ == '__main__':
    for task in tasks:
        uid = str(uuid.uuid4())
        thread_id.append(uid)
        t = Thread(target=http_handler, args=(uid, task, False), name=uid)
        t.start()

    print thread_id

    # Wait Time X or until user is doing something
    # Send flag = to desired thread to indicate the loop should stop after reaching the end.

Any suggestions? 有什么建议么? What is the best solution? 最好的解决方案是什么? I don't want to kill the thread because I would like to read the ending to have a full XML message. 我不想杀死线程,因为我想阅读结尾以获取完整的XML消息。

I found a solution by using threading module and threading.events. 我通过使用线程模块和threading.events找到了解决方案。 Maybe not the best solution, but it works fine currently. 也许不是最好的解决方案,但目前效果很好。

import logging
import threading
import time
import uuid
import requests

logging.basicConfig(level=logging.DEBUG, format='(%(threadName)-10s) %(message)s', )

tasks = ['http://agent.mtconnect.org/sample?interval=5000',
         'http://agent.mtconnect.org/sample?interval=10000']

d = dict()


def http_handler(e, url):
    logging.debug('wait_for_event starting')
    message_buffer = []
    filter_namespace = True

    try:
        requests_stream = requests.get(url, stream=True, timeout=2)
        for line in requests_stream.iter_lines():
            if line:
                message_buffer.append(line)

            if e.isSet() and line.endswith('</MTConnectStreams>'):
                logging.debug(len(message_buffer))
                break

    except requests.exceptions.RequestException as e:
        print('error: ', e)

    except BaseException as e:
        print e


if __name__ == '__main__':
    logging.debug('Waiting before calling Event.set()')
    for task in tasks:
        uid = str(uuid.uuid4())
        e = threading.Event()
        d[uid] = {"stop_event": e}
        t = threading.Event(uid)
        t = threading.Thread(name=uid,
                             target=http_handler,
                             args=(e, task))
        t.start()

    logging.debug('Waiting 3 seconds before calling Event.set()')

    for key in d:
        time.sleep(3)
        logging.debug(threading.enumerate())
        logging.debug(d[key])
        d[key]['stop_event'].set()
    logging.debug('bye')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM