2012-02-07 2 views
5

우리는 작은 c 서버 응용 프로그램을 개발 중입니다. 서버 응용 프로그램은 일부 데이터 처리를 수행하고 클라이언트에 응답합니다. 데이터 처리 부분을 구성 가능하고 유연하게 유지하기 위해 우리는 스크립팅을하기로 결정했고 우리가 Python을 사용하기로 결정한 다양한 준비 모듈의 가용성을 기반으로 결정했습니다. 우리는 Python-C API를 사용하여 c와 python 사이에서 데이터를 보내고받습니다.Python-C API 동시성 문제

알고리즘은 다음과 같이 작동합니다 : -

  1. 서버는 클라이언트에서 일부 데이터를 수신하고,이 데이터는 C에서 만든 사전에 저장됩니다. 사전은 API 함수 인 PyDict_New()를 사용하여 생성됩니다. c. 입력은 API 함수 PyDict_SetItemString()을 사용하여 사전에 키 값 쌍으로 저장됩니다.
  2. 다음으로 python 스크립트 PyRun_SimpleString()을 실행합니다. 스크립트를 매개 변수로 전달합니다. 이 스크립트는 c에서 작성된 사전을 사용합니다. PyImport_AddModule() 메소드를 사용하여 스크립트에서 액세스 할 수있는 사전을 c로 작성합니다. 및 PyModule_AddObject();
  3. 우리는 데이터 처리 결과를 위에서 작성한 동일한 사전의 키 값 쌍으로 스크립트에 저장합니다. 그런 다음 C 코드는 스크립트가 실행 된 후 결과 변수 (키 - 값 쌍)에 액세스 할 수 있습니다.

우리가 직면하고있는 문제는 서로 다른 클라이언트에서 들어오는 동시 요청의 경우에 문제 . 다른 클라이언트에서 여러 요청이 들어올 때 우리는 참조 횟수 예외를 처리하는 경향이 있습니다. 사용자를 위해 들어오는 요청마다 해당 사용자에 대한 독립적 인 사전을 만듭니다. 이 문제를 극복하기 위해 우리는 PyRun_SimpleString()에 대한 호출을 포괄했습니다. PyEval_AcquireLock() 내에서; 및 PyEval_ReleaseLock();을 사용하지만 스크립트 실행이 차단 호출이됩니다. 따라서 스크립트 실행에 시간이 오래 걸리는 경우 다른 모든 사용자도 응답을 기다리고 있습니다.

가능한 최선의 방법을 제안하거나 잘못된 정보를 알려주십시오. 자세한 정보는 ping하십시오.

도움이나 도움을 받으실 수 있습니다.

답변

1

아마 this answer에 언급 된 통화 중 하나가 누락되었습니다.

+0

Jane에게 문의 해 주셔서 감사합니다. 덧붙여 말하자면, 나는 그 함수를 호출했지만 여전히 작동하지 않을 것이다. – Will

1

아마도 http://docs.python.org/c-api/init.html#thread-state-and-the-global-interpreter-lock을 읽어야합니다. 문제는 첫 번째 단락에서 설명합니다.

GIL을 획득하면 Python 개체를 직접 조작해야합니다. PyRun_SimpleString에 대한 호출은 내부적으로 GIL을 처리 할 것이고 장기 실행 연산 또는 모든 X 명령어에서만 포기할 것입니다. 그러나 실제로는 멀티 스레드가 아닙니다.

편집 :

당신은 잠금을 획득 할 필요가 당신은 파이썬이 다른 스레드 상태에 걸 알고 있는지 확인해야합니다 :

// acquire the lock and switch thread state 
PyEval_AcquireLock(); 
PyThreadState_Swap(perThreadState); 

// execute some python code 
PyEval_SimpleString("print 123"); 

// clear the thread state and release the lock 
PyThreadState_Swap(NULL); 
PyEval_ReleaseLock(); 
+0

안녕하세요. Tom, 답변 해 주셔서 감사합니다. 진정으로 멀티 스레드가 아닌 "사실"에 대해 자세히 설명해 주시겠습니까?스크립트가 병렬로 실행될 수 없다는 것을 의미합니까? – Will

+0

전역 인터프리터 잠금이 있습니다. 파이썬 바이트 코드 명령어는 아무리 많은 스레드가 있더라도 한 번에 하나만 실행됩니다. 파일과 같은 장기 실행 함수는 잠금이 실행되는 동안 잠금을 일시적으로 해제하고 파이썬 인터프리터는 주기적으로 잠금을 포기하지만 궁극적으로 한 프로세스 내에서 파이썬 바이트 코드는 순차적으로 실행됩니다. –

+0

그 톰을 보내 주셔서 감사합니다. 응답 시간을 보내 주시면 감사하겠습니다. 이것을 확인하십시오 : PyRun_SimpleString이 2 개의 (또는 아마도 n 개의) 분리 된 "c"쓰레드로 실행되고 있다면 GIL 자체를 처리하므로 어떤 쓰래드에서든 PyRun_SimpleString을 호출하기 전에 차단하거나 잠글 필요가 없습니다. – Will

1

난 당신이 multiprocessing 모듈을 조사 좋습니다.