第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Cython,Python和KeyboardInterrupt被忽略

Cython,Python和KeyboardInterrupt被忽略

尚方寶劍之說 2021-03-12 15:11:37
有沒有一種方法可以Ctrl+C基于Cython擴展中嵌入的循環(huán)來中斷()Python腳本?我有以下python腳本:def main():    # Intantiate simulator    sim = PySimulator()    sim.Run()if __name__ == "__main__":    # Try to deal with Ctrl+C to abort the running simulation in terminal    # (Doesn't work...)    try:        sys.exit(main())    except (KeyboardInterrupt, SystemExit):        print '\n! Received keyboard interrupt, quitting threads.\n'這會運行一個循環(huán),該循環(huán)是C ++ Cython擴展的一部分。然后,在按Ctrl+C的同時,將KeyboardInterrupt拋出,但將其忽略,并且程序將繼續(xù)進行直到模擬結束。我發(fā)現(xiàn)的解決方法是通過捕獲SIGINT信號來處理擴展中的異常:#include <execinfo.h>#include <signal.h>static void handler(int sig){  // Catch exceptions  switch(sig)  {    case SIGABRT:      fputs("Caught SIGABRT: usually caused by an abort() or assert()\n", stderr);      break;    case SIGFPE:      fputs("Caught SIGFPE: arithmetic exception, such as divide by zero\n",            stderr);      break;    case SIGILL:      fputs("Caught SIGILL: illegal instruction\n", stderr);      break;    case SIGINT:      fputs("Caught SIGINT: interactive attention signal, probably a ctrl+c\n",            stderr);      break;    case SIGSEGV:      fputs("Caught SIGSEGV: segfault\n", stderr);      break;    case SIGTERM:    default:      fputs("Caught SIGTERM: a termination request was sent to the program\n",            stderr);      break;  }  exit(sig);}然后 :signal(SIGABRT, handler);signal(SIGFPE,  handler);signal(SIGILL,  handler);signal(SIGINT,  handler);signal(SIGSEGV, handler);signal(SIGTERM, handler);我不能通過Python或至少從Cython進行這項工作嗎?當我要在Windows / MinGW下移植我的擴展程序時,我希望有一些不特定于Linux的東西。
查看完整描述

2 回答

?
慕虎7371278

TA貢獻1802條經驗 獲得超4個贊

您必須定期檢查未決信號,例如,在模擬循環(huán)的第N次迭代中:


from cpython.exc cimport PyErr_CheckSignals


cdef Run(self):

    while True:

        # do some work

        PyErr_CheckSignals()

PyErr_CheckSignals將運行與信號模塊一起安裝的信號處理程序(KeyboardInterrupt必要時包括升高)。


PyErr_CheckSignals速度非???,可以經常調用它。請注意,應該從主線程調用它,因為Python在主線程中運行信號處理程序。從輔助線程調用它無效。


解釋


由于信號是在不可預測的時間異步傳遞的,因此直接從信號處理程序運行任何有意義的代碼是有問題的。因此,Python將傳入的信號排隊。該隊列稍后作為解釋器循環(huán)的一部分進行處理。


如果您的代碼已完全編譯,則解釋器循環(huán)將永遠不會執(zhí)行,并且Python沒有機會檢查和運行排隊的信號處理程序。


查看完整回答
反對 回復 2021-03-27
?
婷婷同學_

TA貢獻1844條經驗 獲得超8個贊

如果您嘗試處理KeyboardInterrupt釋放GIL的代碼(例如,因為它使用cython.parallel.prange),則需要重新獲取GIL才能調用PyErr_CheckSignals。以下代碼段(改編自上面的@ nikita-nemkin的答案)說明了您需要執(zhí)行的操作:


from cpython.exc cimport PyErr_CheckSignals

from cython.parallel import prange


cdef Run(self) nogil:

    with nogil:

        for i in prange(1000000)

            # do some work but check for signals every once in a while

            if i % 10000 == 0:

                with gil:

                    PyErr_CheckSignals()


查看完整回答
反對 回復 2021-03-27
  • 2 回答
  • 0 關注
  • 258 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網(wǎng)微信公眾號