2010-02-04 3 views
-1

이 질문은 내가 여기에서 물어 본 다른 사람들과 관련이있다. 주로 거대한 데이터 세트를 메모리에 정렬하는 것에 관한 것이다.Python : deferToThread XMLRPC 서버 - 뒤틀린 - Cherrypy?

트위스트 XMLRPC 서버를 실행 :

기본적으로 이것은 내가/가지고 싶은 것입니다. 이 서버는 Foo 클래스의 여러 인스턴스를 메모리에 유지합니다. 각 Foo 클래스는 목록 막대 (몇 백만 개의 레코드가 포함되어 있음)를 포함합니다. 데이터베이스에서 데이터를 검색하여 XMLRPC 서버에 전달하는 서비스가 있습니다. 데이터는 각 푸 인스턴스에 대응하는 키를, 기본적으로 사전이며, 값과 같이, 사전의 목록이다 :

data = {'foo1':[{'k1':'v1', 'k2':'v2'}, {'k1':'v1', 'k2':'v2'}], 'foo2':...} 

각 푸 인스턴스 그럼 열쇠에 대응하는 값, 및 푸 전달된다. 바 사전이 업데이트되고 정렬됩니다.

class XMLRPCController(xmlrpc.XMLRPC): 

    def __init__(self): 
     ... 
     self.foos = {'foo1':Foo(), 'foo2':Foo(), 'foo3':Foo()} 
     ... 

    def update(self, data): 
     for k, v in data: 
      threads.deferToThread(self.foos[k].processData, v) 

    def getData(self, fookey): 
     # return first 10 records of specified Foo.bar 
     return self.foos[fookey].bar[0:10] 

class Foo(): 

    def __init__(self): 
     bar = [] 

    def processData(self, new_bar_data): 
     for record in new_bar_data: 
      # do processing, and add record, then sort 
      # BUNCH OF PROCESSING CODE 
      self.bar.sort(reverse=True) 

문제는 업데이트 기능이 기록의 많은으로 XMLRPCController에서 호출 될 때 모든 (32 개) 푸 인스턴스가 process_data 방법을 완료 할 때까지 내 GetData의 호출에 응답하지 (100K + 말)이다. deferToTread가 작동 할 것이라고 생각했지만 문제가있는 곳을 오해하고있는 것 같습니다.

제안 사항 ... 필요한 동작을 지원하는 경우 Cherrypy와 같은 다른 것을 사용하고 있습니다.


편집

@Troy :이 원자로는 지금까지 GIL로

reactor.listenTCP(port_no, server.Site(XMLRPCController) 
reactor.run() 

을 설정하는 방법이다이 sys.setcheckinterval을 변경할 수있는 실행 가능한 옵션이 될 것이다 () 값이 더 작아서 데이터의 잠금이 해제되어 읽을 수 있습니까?

답변

1

응용 프로그램을 반응시키는 가장 쉬운 방법은 CPU를 많이 사용하는 처리를 더 작은 덩어리로 분해하면서 트위스트 된 반응기를 실행시키는 것입니다. 예를 들어 reactor.callLater (0, process_next_chunk)를 호출하여 다음 청크로 진행합니다. 혼자서 협력적인 멀티 태스킹을 효과적으로 구현하십시오.

또 다른 방법으로 작업을 수행하기 위해 별도의 프로세스를 사용하면 여러 코어의 이점을 얻을 수 있습니다. Ampoule 살펴보기 : https://launchpad.net/ampoule deferToThread와 비슷한 API를 제공합니다.

+0

각 Foo 인스턴스를 자체 하위 프로세스에 배치하는 것은 적어도 처음에는 시도해 볼만한 것처럼 들립니다. –

0

processData 메소드가 실행되는 기간이나 트위스트 리액터를 설정하는 방법을 알 수 없습니다. By default의 경우, 비틀림 반응기는 0 내지 10 개의 나사산을 갖는다. 32 개의 장기 실행 계산을 10 개의 스레드까지 연기하려고 할 수 있습니다. 이것은 차선책입니다.

또한 모든 컬렉션을 업데이트 할 때 GIL이 어떤 역할을하는지 묻는 것이 좋습니다.

편집 : 프로그램을 심각하게 변경하기 전에 (예 : sys.setcheckinterval()을 호출) 프로파일 러 또는 python 추적 모듈을 사용하여 실행해야합니다. 이것들은 당신의 모든 시간을 사용하고있는 방법을 알려줄 것입니다. 올바른 정보가 없으면 바꿀 수 없습니다.

관련 문제