天道酬勤,学无止境

如何使用键盘中断 Python 中的 recvfrom() 调用?(How can I interrupt a recvfrom() call in Python with keyboard?)

问题

我在程序的 main() 函数中运行了一个循环,如下所示

while True:
    data, addr = sock.recvfrom(MAX_MESS_LEN)
    thread.start_new_thread(message_handler, (data, addr,))

我想介绍一些功能,让我可以点击“q”来跳出循环并结束程序。 我不确定如何执行此操作,因为程序会等待 recvfrom() 调用,直到收到消息。 有没有办法实现中断键或键盘事件捕获器之类的? 现在我使用 ctrl-c 来键盘中断程序,但这似乎有点草率。

回答1

您可以先尝试检查套接字中是否有任何数据,然后再尝试从它接收数据?

dataInSocket, _, _ = socket.select.select([sock], [], [])
if dataInSocket:
    data, addr = sock.recvfrom(MAX_MESS_LEN)
    thread.start_new_thread(message_handler, (data, addr,))

我在这里有点猜到了你的代码,所以这段代码可能不会干净地复制和粘贴到你的代码中。 您需要使其适用于您自己的程序。

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 调试模式PyCharm中的键盘中断(Keyboard interrupt in debug mode PyCharm)
    问题 在调试模式下,有什么方法可以在PyCharm IDE(3.1)中发送键盘中断事件吗? 回答1 不幸的是,没有简单的方法可以做到这一点。 您将需要使用psutil和signal模块。 为此,您需要安装psutil ,最好的方法是通过pip : pip install psutil 因此,假设我们在这里展示了A: while True: try: time.sleep(3) print "Zzzz" time.sleep(3) print("gong!") except KeyboardInterrupt as e: print "Closed by an Interrupt" break 您正在PyCharm中运行它。 确保您使用的解释器已安装psutils 。 您可以检查: 确保正确设置了解释器: 如果尚未安装psutil ,则始终可以通过“安装”按钮进行安装。 好的,现在我们已经完成所有设置,让我们调试程序: 现在,我们要做的就是获取进程ID,我们可以在程序开始时获取它: 因此,让我们启动控制台并发送信号: 如果工作正常,您应该看到while循环结束: 您可以通过在控制台的启动脚本中添加发送中断的功能来进一步简化流程: 一旦完成所有这些操作,您需要做的就是调用interrupt(<pid here>)来调用进程中的键盘中断。 我希望能回答您的问题。 回答2 PyCharm的
  • 如何在不杀死解释器的情况下中断本机扩展代码?(How to interrupt native extension code without killing the interpreter?)
    问题 我正在开发一个项目,该项目将用 C++ 编写的高性能算法与 Python 接口相结合。 C++ 类和函数通过 Cython 编译器包装并暴露给 Python。 假设我从 Python 解释器(我的首选是 IPython)调用一个长时间运行的本机函数。 是否有可能在不杀死解释器的情况下中断或中止该代码的执行? 回答1 这是 Ricardo C. 建议的使用multiprocessing的可能实现, import multiprocessing as mpr def dangerwrap(f): """ I assume f is, or eventually calls, some external function, like cython wrapped C/C++. Also assuming that f returns an object and takes no parameters """ event = mpr.Event() q = mpr.Queue() def signalling_f(): q.put(f()) event.set() f_process = mpr.Process(target = signalling_f) f_process.start() try: event.wait() except KeyboardInterrupt: f
  • 键盘中断与 python 的多处理池和映射函数(Keyboard Interrupts with python's multiprocessing Pool and map function)
    问题 我发现这篇文章解释了如何使用 ctr+c 终止正在运行的多处理代码。 以下代码完全正常工作(可以使用 ctrl+c 终止它): #!/usr/bin/env python # Copyright (c) 2011 John Reese # Licensed under the MIT License import multiprocessing import os import signal import time def init_worker(): signal.signal(signal.SIGINT, signal.SIG_IGN) def run_worker(): time.sleep(15) def main(): print "Initializng 5 workers" pool = multiprocessing.Pool(5, init_worker) print "Starting 3 jobs of 15 seconds each" for i in range(3): pool.apply_async(run_worker) try: print "Waiting 10 seconds" time.sleep(10) except KeyboardInterrupt: print "Caught KeyboardInterrupt
  • 如何在Linux内核中生成“人为”中断?(How would one go about generating “artificial” interrupts in the Linux Kernel?)
    问题 我在这里阅读了答案:触发内核中断处理程序:如何? 这是一个很好的选择,但不是我所需要的。 我在处理中断方面对RNG函数进行了微基准测试,因此我需要一种人为且可重复生成中断的好方法。 例如,我可以将某些东西重定向到Procfs接口中,该接口会生成300次中断或类似的中断。 它像在内核中运行某种产生中断的函数一样容易吗? 是否存在某种实际上不执行“ Anything”但仍然经过整个中断处理程序路径的中断? 我意识到我只能键入键或类似的东西,但出于研究目的,这实际上并不是可重复的且可编写脚本的。 我正在使用x86体系结构。 回答1 这是一个可能生成伪造的键盘中断的潜在解决方案,根据内核的PoV,无法判断这些中断不是真实的。 只有安装了SA_SAMPLE_RANDOM的中断处理程序才会生成熵,从而消除了为此目的而进行的系统调用。 但是,键盘中断的确会产生熵。 我没有测试以下代码,也无法提供任何保证,但是我认为,如果作为内核模块的一部分运行,它应该可以工作。 下面的代码片段显示了如何将按键强制插入键盘控制器的缓冲区中。 如果未插入真正的PS / 2键盘(或BIOS中支持传统USB的USB键盘),则此功能将不起作用。此代码是从Phrack上的SMM键盘记录器文章中复制的 该代码在x86汇编中,您可以将其包装在嵌入式汇编块中asm(""); 如果您使用C编写内核模块。 ; write
  • 如何在 PyQt 中将按钮设置为键盘中断(How to set push-button to keyboard interrupt in PyQt)
    问题 通过终端运行程序时,我们可以通过按 'Ctrl+c' 来停止程序,它将显示消息为 'KeyboardInterrupt' 。 那么,有没有办法通过单击 PyQt 中的按钮来做明智的事情。 回答1 如果您的程序正在运行一个循环,您可以定期调用 processEvents 以允许 gui 时间更新(这应该允许您单击按钮关闭应用程序): count = 0 while True: count += 1 if not count % 50: QtGui.qApp.processEvents() # do stuff... 回答2 在我中断无限循环的脚本中,我还使用了QtGui.qApp.processEvents()并且效果很好。 无限循环从串行端口写入和读取数据,用户可以使用按钮(1.condition)中断循环。 def Move_Right(self): # move the slide right cmdPack = struct.pack(cmdStruct, Address, Rotate_Right, 0, Motor5, Speed5) dataByte = bytearray(cmdPack) checksumInt = sum(dataByte[:]) % 256 msgPack = struct.pack(msgStruct, Address, Rotate
  • Python中的键盘可中断阻塞队列(Keyboard interruptable blocking queue in Python)
    问题 它似乎 import Queue Queue.Queue().get(timeout=10) 键盘可中断 (ctrl-c) 而 import Queue Queue.Queue().get() 不是。 我总是可以创建一个循环; import Queue q = Queue() while True: try: q.get(timeout=1000) except Queue.Empty: pass 但这似乎是一件奇怪的事情。 那么,有没有办法获得无限期等待但键盘可中断的 Queue.get()? 回答1 Queue对象具有此行为,因为它们使用来自threading模块的Condition对象进行锁定。 因此,您的解决方案确实是唯一的出路。 但是,如果您真的想要一个执行此操作的Queue方法,您可以对Queue类进行猴子补丁。 例如: def interruptable_get(self): while True: try: return self.get(timeout=1000) except Queue.Empty: pass Queue.interruptable_get = interruptable_get 这会让你说 q.interruptable_get() 代替 interruptable_get(q) 尽管 Python
  • 键盘中断与python的多处理池(Keyboard Interrupts with python's multiprocessing Pool)
    问题 如何使用python的多处理池处理KeyboardInterrupt事件? 这是一个简单的示例: from multiprocessing import Pool from time import sleep from sys import exit def slowly_square(i): sleep(1) return i*i def go(): pool = Pool(8) try: results = pool.map(slowly_square, range(40)) except KeyboardInterrupt: # **** THIS PART NEVER EXECUTES. **** pool.terminate() print "You cancelled the program!" sys.exit(1) print "\nFinally, here are the results: ", results if __name__ == "__main__": go() 当运行上面的代码时,按^C会引发KeyboardInterrupt ,但是该过程只是在此时挂起,因此我必须在外部将其杀死。 我希望能够随时按^C并导致所有进程正常退出。 回答1 这是一个Python错误。 等待threading.Condition.wait()中的条件时
  • 如何中断BufferedReader的readLine(How to interrupt BufferedReader's readLine)
    问题 我试图在多个线程中逐行读取套接字的输入。 如何中断readLine()以便可以正常停止正在阻塞的线程? 编辑(赏金) :可以在不关闭套接字的情况下完成此操作吗? 回答1 关闭中断线程上的套接字。 这将导致在中断的线程上引发异常。 有关此和其他并发问题的更多信息,我强烈推荐Brian Goetz的书“ Java并发实践”。 回答2 在不关闭套接字的情况下: 困难的问题不是BufferedReader.readLine ,而是底层的read 。 如果一个线程被阻止读取,唯一的方法就是提供一些实际数据或关闭套接字(中断线程可能应该起作用,但实际上不行)。 因此,显而易见的解决方案是拥有两个线程。 读取原始数据的文件,将保持被阻止状态。 第二个是调用readLine的线程。 管道数据从第一个到第二个。 然后,您将拥有一个可以用来唤醒第二个线程的锁,并可以采取适当的措施。 有变化。 您可以使第一个线程使用NIO,并在所有使用者之间共享一个线程实例。 或者,您可以编写一个可与​​NIO一起使用的readLine 。 由于Selector.wakeup存在并且可以正常工作,因此甚至可以采用相对简单的单线程形式。 回答3 对不起,迟到了6年;-)对于一个简单的爱好控制台应用程序,从键盘上读取时,我需要一些可中断的readLine。 换句话说,我无法“关闭插座”。 您可能知道, System
  • 使用键盘中断关闭所有线程(Closing all threads with a keyboard interrupt)
    问题 我在这里试图做的是使用键盘中断退出程序中所有正在进行的线程。 这是创建线程的代码的精简版本: for i in taskDictionary: try: sleep(60) thread = Thread(target = mainModule.executeThread) thread.start() except KeyboardInterrupt: thread.__stop() 程序本身要复杂得多,需要考虑大量影响线程的不同变量,甚至可以选择以顺序模式启动,在顺序模式下,任务没有线程化,而是一个一个地启动,因此可能存在一些问题有了这个小的变化,我就想到了。 我这样做的方式产生了50/50的结果。 中断将起作用,但是线程将永远不会干净退出。 有时他们会继续前进,但停止执行未来的线程,有时它们会退出有关中断的大量错误,而另一些时候,中断根本不会执行任何操作。 上一次我运行该程序时,该程序停止了将来任何线程的执行,但没有停止当前线程。 有什么方法可以退出线程而无需进入线程实际在其中执行的模块吗? 回答1 类似的问题是“如何杀死线程?” 您在线程中创建退出处理程序,该线程由线程模块中的锁或事件对象控制。 然后,您只需删除锁或向事件对象发出信号。 这通知线程它应该停止处理并正常退出。 在主程序中发出线程信号后,剩下要做的就是在main使用thread.join()方法
  • 自定义键盘中断处理程序(Custom keyboard interrupt handler)
    问题 我正在尝试编写一个简单的程序,它将用一个自定义的程序来替换标准键盘中断,该程序将减少一个变量。 但是,如果不调用旧处理程序,它将无法工作。 这是我的中断处理程序: handler proc push ax push di dec EF ;pushf ;when these to instructions commented keyboard interrupts handling hangs ;call [OLD] mov al,20h out 20h,al pop di pop ax iret handler endp 我还应该在处理程序中执行哪些操作以使其在不调用旧处理程序的情况下工作? 回答1 您需要将 DS 保存在堆栈上并将其设置为适合您的程序的值,然后在iret之前恢复它。 这部分: mov al,20h out 20h,al 确认中断。 如果您调用 BIOS 中断处理程序,那么您不应该也这样做,因为 BIOS 处理程序会这样做。 回答2 在您从键盘缓冲区读取当前数据之前,您不会从键盘接收任何进一步的数据。 在将 EOI 发送给 PIC 之前使用 in al,60h 读取当前等待处理的扫描码。 调用旧的中断处理程序的原因是因为它确实从键盘读取了等待的数据。 正如 Michael Slade 所指出的,您需要关注这样一个事实
  • 键盘中断与python的多处理(Keyboard Interrupt with python's multiprocessing)
    问题 我在使用python的多处理功能优雅地处理键盘中断时遇到问题 (是的,我知道Ctr-C不应该​​保证正常关机-而是将讨论留给其他线程) 考虑下面的代码,我使用的是multiprocessing.Manager#list() ,它是一个ListProxy,据我了解可以处理对列表的多进程访问。 当我从Ctr-C退出-我收到一个socket.error: [Errno 2] No such file or directory尝试访问ListProxy时socket.error: [Errno 2] No such file or directory 我希望共享列表不被Ctr-C破坏。 这可能吗?! 注意:我想在不使用池和队列的情况下解决此问题。 from multiprocessing import Process, Manager from time import sleep def f(process_number, shared_array): try: print "starting thread: ", process_number shared_array.append(process_number) sleep(3) shared_array.append(process_number) except KeyboardInterrupt: print
  • 禁用中断是什么意思?(what is meant by disabling interrupts?)
    问题 进入中断处理程序时,我们首先在该CPU上“禁用中断”(使用x86上的cli指令之类的东西)。 在禁用中断的时间内,假设用户按下了键盘上的字母“ a”,这通常会导致中断。 但是由于中断被禁用,这是否意味着: 绝不会调用“ a”的中断处理程序,因为在关键部分或中断将由os处理,但会延迟,直到再次允许中断为止。 具体来说,如果用户第一次按下“ a”是在禁用中断的时间,用户是否需要再次按下“ a”? 回答1 通常,一个中断被硬件“排队”。 [中断通常只是一个可以持续的逻辑门; 一旦打开,它会保持一段时间。] 如果用户仅在禁用中断的间隔内单击一次“ a”,则在重新启用中断时它将注册为中断。 如果用户在中断被禁用的间隔内设法以某种方式两次击中“ a”,则当中断被启用时,用户将注册为中断。 是第一个还是第二个取决于确切的逻辑门配置。 回答2 答案是,这取决于您是否已经在处理键盘中断。 大多数中断服务程序(ISR)在其终止处都具有代码,该代码通知硬件已被“服务”。 对于键盘控制器,命令将写入其中,以确认接收到的字节。 在确认时,键盘控制器硬件停止使用电来发出中断信号。 如果您正在处理非键盘中断,比如说火警中断,那么以电子方式断言该中断的键盘硬件将在按下键时触发。 电气信号将被忽略,直到CPU再次启用中断为止。 在对火警中断进行服务结束时,火警ISR确认所有数据并重新启用CPU上的中断。 立即
  • 覆盖默认的 INT 9h(Override default INT 9h)
    问题 我试图在按下某个键时覆盖默认中断。 这是我的代码:我不明白为什么它不起作用,它适用于其他 INT 数字(例如 43h) mov al,9h mov ah,25h mov bx,seg int9h mov ds,bx mov dx,offset int9h int 21h (其中 int9h 是我代码中的标签)有谁知道如何在按下某个键时挂钩中断? 谢谢 ! 编辑: mov ax,2509h mov dx,offset int9h int 21h int9h PROC ;do some stuff IRET int9h ENDP 回答1 我会尝试再次回答这个问题 - 以一种有点冗长的方式。 在 Windows 流行之前,DOS 统治着计算机。 为了扩展其功能,人们习惯于编写TSR(终止并驻留)程序; 这些程序会挂钩各种中断功能(例如时钟和键盘),终止并驻留在内存中。 因此,当给定的中断发生时,这些实用程序的驻留代码将处理中断,可能会调用原始中断处理程序。 此类程序将具有由两部分组成的结构:临时部分和驻留部分。 瞬态部分是从命令行调用程序时运行的代码; 这将检查是否已经安装了常驻部分。 如果已经安装了居民的一部分,该计划只会退出,但如果这是第一次调用,该计划将首先保存当前中断处理程序的地址,然后再安装它自己的代码作为新的中断处理程序,然后进行特殊DOS
  • 如何在Python中捕获SIGINT?(How do I capture SIGINT in Python?)
    问题 我正在研究启动多个进程和数据库连接的python脚本。 我不时地想用Ctrl + C信号杀死脚本,我想进行一些清理。 在Perl中,我可以这样做: $SIG{'INT'} = 'exit_gracefully'; sub exit_gracefully { print "Caught ^C \n"; exit (0); } 我该如何在Python中做类似的事情? 回答1 使用signal.signal注册您的处理程序,如下所示: #!/usr/bin/env python import signal import sys def signal_handler(sig, frame): print('You pressed Ctrl+C!') sys.exit(0) signal.signal(signal.SIGINT, signal_handler) print('Press Ctrl+C') signal.pause() 从此处改编的代码。 可以在这里找到有关signal更多文档。 回答2 您可以像对待其他异常一样将其视为异常(KeyboardInterrupt)。 制作一个新文件,并从您的外壳运行以下内容,以了解我的意思: import time, sys x = 1 while True: try: print x time.sleep(.3) x += 1
  • 在python中中断/中断time.sleep()(break/interrupt a time.sleep() in python)
    问题 我需要使用ctrl c从time.sleep()中断。 While 1: time.sleep(60) 在上面的代码中,当控件进入time.sleep函数时,整整60秒需要经过python处理CTRL C 有什么优雅的方法可以做到这一点。 这样我就可以在控件处于及时状态时中断我的睡眠功能 编辑 我在一个旧的实现中进行了测试,该实现在Windows 2000上使用python 2.2,这引起了所有麻烦。 如果我使用的是更高版本的python,则CTRL C会中断sleep()。 我通过在for循环内调用sleep(1)进行了快速破解。 暂时解决了我的问题 回答1 不确定这段代码的含义是什么-但如有必要,请使用更短的sleep()间隔并在其周围放置一个for循环: for i in range(60): sleep(1) 使用try..except捕获KeyboardInterrupt异常很简单 回答2 正确的答案是使用python stdlib的threading.Event 当然,您可以调低睡眠间隔,使您的睡眠时间很短,但是如果您实际上想每60秒钟运行一次循环,该怎么办? 然后,您需要做更多的工作来确定是该运行还是该保持睡眠状态。 此外,从技术上讲,您仍然处于阻塞状态,但时间很短。 与threading.Event : from threading import Event
  • pygame 需要键盘中断来初始化显示(pygame requires keyboard interrupt to init display)
    问题 我正在尝试在 Raspberry Pi 上初始化 pygame,它需要键盘中断才能执行任何操作。 这是我的代码: os.putenv ( "SDL_VIDEODRIVER" , "fbcon" ) pygame.display.init() # It hangs here screen = pygame.display.set_mode ( ( 1024 , 768 ) ) pygame.draw.rect ( screen , ( 0 , 255 , 0 ) , ( 15 , 15 , 15 , 15 ) ) pygame.display.flip() keyLoop = True while keyLoop: for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_DOWN: print ( "Down arrow pressed, exiting" ) keyLoop = False pygame.quit() 我在这里发现了一个类似的问题,Python 程序在键盘中断之前不会响应,但它不会让我添加评论,我已经尝试了他们的所有建议,但仍然存在问题。 如果我按 CTRL + C 然后我的图形出现,但键盘不起作用。 谢谢 编辑 我通过完全删除 os
  • 键盘中断与python gtk吗?(keyboard interrupt with with python gtk?)
    问题 因此,正如问题所言,我试图让键盘中断在Gtk.main()进行时发生,但是,似乎直到功能完成后才注意到键盘中断发生了。 因此,我尝试将Gtk.main()粘贴在单独的线程中,并让主线程找到键盘中断,并终止线程,但随后发现Gtk不能很好地与本文所述的线程配合使用 我想不出任何其他方法来让键盘中断起作用。 这可能吗? 我正在使用python3,希望我的程序最终可以跨平台。 回答1 由于使用pygobject编写的https://bugzilla.gnome.org/show_bug.cgi?id=622084 gtk应用程序在终端上使用Ctrl + C时不会自行关闭。 要解决此问题,您可以安装一个Unix信号处理程序,如下所示: if __name__ == '__main__': import signal signal.signal(signal.SIGINT, signal.SIG_DFL) your_application_main() 回答2 接受的答案对我不起作用。 我通过将GLib.MainLoop().run()替换为Gtk.main()来解决该问题,如错误报告中所述。 回答3 使用信号模块覆盖SIGINT处理程序(python线程上100%CPU)时,我也遇到麻烦; 对我来说,另一种选择是: def main(): self.mainloop = GObject
  • x86 汇编中断服务例程可以调用另一个中断吗?(Can an x86 assembly interrupt service routine call another interrupt?)
    问题 我可以在独立的 x686 环境中从中断服务例程中调用中断吗? 因此,可以执行以下操作: isr: pusha call doSomething int 21h popa iret 如果可能,那么这些嵌套的中断是否有任何明显的塌陷? 回答1 中断调用类似于带有推送标志的常规call 。 而iret所做的是返回并弹出标志。 所以,是的,可以递归调用中断。 由于硬件中断在系统上连续运行,实际上在另一个中断处理程序中调用中断一直发生,除非您当然禁用它们。 硬件中断有进一步的限制,通常不会在完成处理之前在同一处理程序中调用。 中断处理程序通过向中断控制器发送信号通知硬件提供新的中断。 回答2 虽然处理器对嵌套中断没有基本限制,但 MS-DOS 和 BIOS 服务不可重入。 也就是说,在硬件中断期间调用它们通常是不安全的,因为在 CPU 已经在执行 MS-DOS 或 BIOS 功能时可能会发生中断。 要从硬件中断服务例程中使用 MS-DOS 和 BIOS 服务,您可以采取许多步骤来确保它们可以安全使用。 您需要做的事情相当复杂,除此之外,您还需要监视 InDos 标志并挂钩其他中断,因此我将向您指出汇编语言编程艺术中有关可重入的部分。 它在涵盖所有细节方面做得非常好。 这是该部分的摘录。 这只是您可能需要做的一部分: MS-DOS 提供了一个特殊的单字节标志 (InDOS),如果 DOS
  • Linux内核:如何捕获按键并用另一个按键代替?(Linux Kernel: How to capture a key press and replace it with another key?)
    问题 我试图涉足低级编程。 我的目标是让用户在终端中键入一个密钥,捕获该密钥并输出另一个密钥。 因此,例如,如果用户键入“ a”,我将键入“ b”,如果用户键入“ b”,我将输出“ c”,依此类推。 这样做的步骤是什么? 我已经熟悉如何访问Linux内核源代码,对其进行编译和使用。 谢谢。 回答1 考虑下一个简单的内核模块: #include <linux/kernel.h> #include <linux/module.h> #include <linux/interrupt.h> #include <asm/io.h> #define KBD_IRQ 1 /* IRQ number for keyboard (i8042) */ #define KBD_DATA_REG 0x60 /* I/O port for keyboard data */ #define KBD_SCANCODE_MASK 0x7f #define KBD_STATUS_MASK 0x80 static irqreturn_t kbd2_isr(int irq, void *dev_id) { char scancode; scancode = inb(KBD_DATA_REG); /* NOTE: i/o ops take a lot of time thus must be avoided in HW
  • python udp socket.recvfrom(bufsize[, flags])(从套接字接收数据)
    socket.recvfrom(bufsize[, flags]) Receive data from the socket. The return value is a pair (bytes, address) where bytes is a bytes object representing the data received and address is the address of the socket sending the data. See the Unix manual page recv(2) for the meaning of the optional argument flags; it defaults to zero. (The format of address depends on the address family — see above.) 从套接字接收数据。 返回值是一对(字节,地址),其中字节是代表接收到的数据的字节对象,而地址是发送数据的套接字的地址。 有关可选参数标志的含义,请参见Unix手册页recv(2)。 它默认为零。 (地址格式取决于地址系列-参见上文。) Changed in version 3.5: If the system call is interrupted and the signal handler does