문제

Python 통역사를 C 프로그램에 포함하고 있습니다. 그러나 일부 파이썬 스크립트를 통해 PyRun_SimpleString() 무한 루프로 실행되거나 너무 오랫동안 실행됩니다. 고려하다 PyRun_SimpleString("while 1: pass"); 메인 프로그램이 차단되는 것을 방지하면서 스레드에서 통역사를 실행할 수 있다고 생각했습니다.

전체 프로세스를 죽이지 않고 스레드에서 실행되는 임베디드 인터프리터에서 Python 스크립트 실행을 중지하려면 어떻게해야합니까?

통역사에게 예외를 전달할 수 있습니까? 신호를 듣는 다른 스크립트 아래에서 스크립트를 래핑해야합니까?

추신 : 나는 별도의 과정에서 파이썬을 실행할 수 있지만 이것이 마지막 수단이 아니라면 이것이 내가 원하는 것이 아닙니다 ...


업데이트:

그래서 지금 작동합니다. 다시 한번 Denis Otkidach에게 감사합니다!

내가 이것을 옳게 보이면, 당신은 두 가지 일을해야합니다 : 통역사에게 멈추고 return -1 pyrun_simplestring ()과 같은 스레드에서 실행 중입니다.

멈추기 위해 몇 가지 가능성이 있습니다. PyErr_SetString(PyExc_KeyboardInterrupt, "...") 또는 PyErr_SetInterrupt() - 첫 번째는 Python이 몇 가지 더 지침을 실행 한 다음 중지 된 다음 나중에 실행을 막을 수 있습니다.

에게 return -1 너는 사용한다 Py_AddPendingCall() 함수 호출을 Python 실행에 주입합니다. 문서는 버전 2.7과 3.1 이후에 언급하고 있지만 이전의 Pythons에서도 실행됩니다 (2.6 여기). 2.7과 3.1에서도 스레드 안전이어야하므로 길 (?)을 획득하지 않고 호출 할 수 있습니다.

따라서 예제를 다시 작성할 수 있습니다.

int quit() {
    PyErr_SetInterrupt();
    return -1;
}
도움이 되었습니까?

해결책

당신이 사용할 수있는 Py_AddPendingCall() 다음 점검 간격에서 호출 할 예외 제외 기능을 추가하려면 (문서 켜기 참조 sys.setcheckinterval() 더 많은 정보를 위해서). 다음은 다음과 같은 예입니다 Py_Exit() 전화 (나에게 효과가 있지만 아마도 필요한 것은 아님), 그것을 대체하십시오. Py_Finalize() 또는 하나의 PyErr_Set*():

int quit(void *) {
    Py_Exit(0);
}


PyGILState_STATE state = PyGILState_Ensure();
Py_AddPendingCall(&quit, NULL);
PyGILState_Release(state);

이것은 순수한 파이썬 코드에 충분해야합니다. 그러나 일부 C 함수는 단일 작업으로 잠시 동안 실행될 수 있습니다 (오랜 REGEXP 검색의 예제가 있었지만 여전히 관련이 있는지 확실하지 않습니다).

다른 팁

Python 통역사는 임베딩 프로그램과 별도의 스레드로 실행되어야합니다. 그렇지 않으면 통역사를 방해 할 기회를 얻지 못할 것입니다.

당신이 그것을 가지고 있다면, 아마도 당신은 아마도 Python API 예외 호출 중 하나를 사용하여 통역사에서 예외를 트리거 할 수 있습니까? 보다 Python C API 예외

무한 루프 취소 또는 장기 실행 코드를 포함하여 적극적으로 실행되는 Python 코드 블록을 방해 할 수 있기를 원했습니다. 내 응용 프로그램에서는 단일 스레드 파이썬 코드가 제출되고 평가됩니다. 인터럽트 요청은 언제든지 올 수 있습니다. 이 질문과 대답은 실제로 그것을 달성하는 데 중요했습니다.

2019 년 에이 질문을 살펴보면 여기의 해결책은 저에게 효과가 없었습니다. 나는 사용하려고했다 Py_AddPendingCall(&quit, NULL); 상당히 다른 방법으로 호출 된 함수는 예상대로 또는 전혀 실행되지 않았습니다. 이로 인해 제출했을 때 파이썬 엔진이 매달려 결국 충돌했습니다. Py_FinalizeEx(). 나는 마침내 이것에 필요한 것을 발견했다. 대답 비슷한 질문에.

파이썬 엔진을 시작한 후 threading 파이썬 코드의 패키지. 나는 그것을 AC 긴 값으로 구문 분석하고 저장합니다.

인터럽트 함수는 실제로 매우 간단합니다.
PyGILState_Ensure()
PyThreadState_SetAsyncExc(threadId, PyExc_Exception) 이전에서 저장 한 스레드 ID와 일반적인 예외 유형을 사용합니다.
PyGILState_Release()

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top