繁体   English   中英

在Python3的线程池中退出无限循环的安全方法

[英]Safe way to exit an infinite loop within a Thread Pool for Python3

我使用的是Python3模块:

  • requests HTTP GET调用几个粒子光子,这些粒子光子被设置为简单的HTTP服务器

  • 作为客户端,我使用Raspberry Pi(也是一个接入点)作为HTTP客户端 ,它使用multiprocessing.dummy.Pool对上述光子进行HTTP GET请求

轮询程序如下:

def pollURL(url_of_photon):
    """
    pollURL: Obtain the IP Address and create a URL for HTTP GET Request
    @param: url_of_photon: IP address of the Photon connected to A.P.
    """
    create_request = 'http://' + url_of_photon + ':80'
    while True:
        try:
            time.sleep(0.1) # poll every 100ms
            response = requests.get(create_request)
            if response.status_code == 200:
                # if success then dump the data into a temp dump file
                with open('temp_data_dump', 'a+') as jFile:
                    json.dump(response.json(), jFile)
            else:
               # Currently just break
               break
        except KeyboardInterrupt as e:
            print('KeyboardInterrupt detected ', e)
            break

url_of_photon值是从Pi上可用的dnsmasq.leases文件获得的简单IPv4地址

main()函数:

def main():
    # obtain the IP and MAC addresses from the Lease file
    IP_addresses = []
    MAC_addresses = []
    with open('/var/lib/misc/dnsmasq.leases', 'r') as leases_file:
        # split lines and words to obtain the useful stuff.
        for lines in leases_file:
            fields = lines.strip().split()
            # use logging in future
            print('Photon with MAC: %s has IP address: %s' %(fields[1],fields[2]))
            IP_addresses.append(fields[2])
            MAC_addresses.append(fields[1])

            # Create Thread Pool
            pool = ThreadPool(len(IP_addresses))
            results = pool.map(pollURL, IP_addresses)
            pool.close()
            pool.join()

if __name__ == '__main__':
    main()

问题

该程序运行良好,但是当我按CTRL + C时 ,程序不会终止。 在挖掘时我发现这样做的方法是使用CTRL + \\

我如何在pollURL函数中使用它来获得退出程序的安全方法,即执行poll.join()以便不留下剩余的进程?

笔记

从不使用该函数识别KeyboardInterrupt 因此,我在尝试检测CTRL + \\时遇到了麻烦。

pollURL在另一个线程中执行。 在Python中,信号仅在主线程中处理。 因此,SIGINT仅在主线程中引发KeyboardInterrupt。

信号文件

信号和线程

Python信号处理程序总是在主Python线程中执行,即使信号是在另一个线程中接收的。 这意味着信号不能用作线程间通信的手段。 您可以使用线程模块中的同步原语。

此外,只允许主线程设置新的信号处理程序。

您可以通过以下方式实现解决方案(伪代码)。

event = threading.Event()

def looping_function( ... ):
    while event.is_set():
        do_your_stuff()

def main():
    try:
        event.set()
        pool = ThreadPool()
        pool.map( ... )
    except KeyboardInterrupt:
        event.clear()
    finally:
        pool.close()
        pool.join()

暂无
暂无

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

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