我正在使用 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 + \ 时遇到了麻烦。
答案 0 :(得分:2)
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()