2009-08-02 7 views
1

모두들, 내 코드를 디버깅하는 데 약간의 문제가 있습니다. 분명히, 나는 이것이 정말 이상한 찾을멀티 프로세싱 디버깅 오류

import globalFunc 
from globalFunc import systemPrint 
from globalFunc import out 
from globalFunc import debug 
import math 
import time 
import multiprocessing 

""" 
Somehow this is not working well 
""" 
class urlServerM(multiprocessing.Process): 

    """ 
    This calculates how much links get put into the priority queue 
    so to reach the level that we intend, for every query resultset, 
    we will put the a certain number of links into visitNext first, 
    and even if every resultSet is full, we will be able to achieve the link 
    level that we intended. The rest is pushed into another list where 
    if the first set of lists don't have max for every time, the remaining will 
    be spared on these links 
    """ 
    def getPriorityCounter(self, level, constraint): 
       return int(math.exp((math.log(constraint)/(level - 1)))) 


    def __init__(self, level, constraint, urlQ): 
     """limit is obtained via ngCrawler.getPriorityNum""" 
     multiprocessing.Process.__init__(self) 
     self.constraint = int(constraint) 
     self.limit = self.getPriorityCounter(level, self.constraint) 
     self.visitNext = [] 
     self.visitLater = [] 
     self._count = 0 
     self.urlQ = urlQ 


    """ 
    puts the next into the Queue 
    """ 
    def putNextIntoQ(self): 
     debug('putNextIntoQ', str(self.visitNext) + str(self.visitLater)) 
     if self.visitNext != []: 
      _tmp = self.visitNext[0] 
      self.visitNext.remove(_tmp) 
      self.urlQ.put(_tmp) 

     elif self.visitLater != []: 
      _tmp = self.visitLater[0] 
      self.visitLater.remove(_tmp) 
      self.urlQ.put(_tmp) 


    def run(self): 
     while True: 
      if self.hasNext(): 
       time.sleep(0.5) 
       self.putNextIntoQ() 
       debug('process', 'put something in Q already') 
      else: 
       out('process', 'Nothing in visitNext or visitLater, sleeping') 
       time.sleep(2) 
     return 


    def hasNext(self): 
     debug('hasnext', str(self.visitNext) + str(self.visitLater)) 
     if self.visitNext != []: 
      return True 
     elif self.visitLater != []: 
      return True 
     return False 


    """ 
    This function resets the counter 
    which is used to keep track of how much is already inside the 
    visitNext vs visitLater 
    """ 
    def reset(self): 
     self._count = 0 


    def store(self, linkS): 
     """Stores a link into one of these list""" 
     if self._count < self.limit: 
      self.visitNext.append(linkS) 
      debug('put', 'something is put inside visitNext') 
     else: 
      self.visitLater.append(linkS) 
      debug('put', 'something is put inside visitLater') 
     self._count += 1 



if __name__ == "__main__": 
    # def __init__(self, level, constraint, urlQ): 

    from multiprocessing import Queue 
    q = Queue(3) 
    us = urlServerM(3, 6000, q) 

    us.start() 
    time.sleep(2) 

    # only one thread will do this 
    us.store('http://www.google.com') 
    debug('put', 'put completed') 

    time.sleep(3) 

    print q.get_nowait() 
    time.sleep(3) 

을 그리고 이것은 출력

OUTPUT 
DEBUG hasnext: [][] 
[process] Nothing in visitNext or visitLater, sleeping 
DEBUG put: something is put inside visitNext 
DEBUG put: put completed 
DEBUG hasnext: [][] 
[process] Nothing in visitNext or visitLater, sleeping 
DEBUG hasnext: [][] 
[process] Nothing in visitNext or visitLater, sleeping 
Traceback (most recent call last): 
    File "urlServerM.py", line 112, in <module> 
    print q.get_nowait() 
    File "/usr/lib/python2.6/multiprocessing/queues.py", line 122, in get_nowait 
    return self.get(False) 
    File "/usr/lib/python2.6/multiprocessing/queues.py", line 104, in get 
    raise Empty 
Queue.Empty 
DEBUG hasnext: [][] 

입니다 : 아래를보고하십시오. 기본적으로이 코드는 main()에서 테스트 할 때 프로세스를 시작한 다음 http://www.google.com을 클래스의 visitNext에 저장 한 다음 대기열에 푸시되는 것을보고 싶습니다.

그러나 출력에 따르면 내 클래스가 URL에 클래스를 저장하는 것을 완료 했음에도 불구하고 hasNext가 아무 것도 표시하지 않는 것이 매우 이상하다는 것을 알게되었습니다. 어떤 육체가 그 이유를 알고 있습니까? 연속적인 while 루프에서 run()을 작성하는 가장 좋은 방법입니까? 실제로 필요한가? 나는 기본적으로 모듈 다중 처리를 실험하려고하는데,이 클래스에서이 URL을 얻을 필요가있는 다중 처리 (다중 처리) 풀의 작업자 풀이있다 (단일 입력 지점). 대기열을 사용하는 것이 가장 좋은 방법입니까? 모든 작업자가 대기열에서 요청하기 때문에 이것을 "라이브"프로세스로 만들 필요가 있습니까? 그리고 대기열에 무언가를 넣으려는 urlServer에 신호를 보내지 않는 한 덜 귀찮은 방법이라고 생각할 수 없습니다.

+0

아무도 응답 할 기회조차 있기 위해 아마도 많은 코드와 설명을 읽으려고합니다. 10 줄의 코드와 5 줄의 설명으로 문제를 해결할 수 없습니까? – ThomasH

답변

0

다중 처리를 사용 중이므로 메모리는 주 실행과 사용자 서버간에 공유되지 않습니다.

e.e. 나는 이것이 실질적으로 Noop이라고 생각한다 : {us.store('http://www.google.com')} 주 스레드에서 실행될 때 {us}의 주 스레드 표현만을 수정하기 때문이다. {q.get_nowait()} 앞에 {us.hasnext()}을 호출하여 URL이 주 스레드의 메모리에 있는지 확인할 수 있습니다.

공유하려면 모든 목록을 Queue-s 또는 Pipe-s으로 전환해야합니다. 또는 모델을 {threading}으로 변경하면 변경하지 않고도 작업을 수행 할 수 있습니다 (다소 차이가있을 수 있습니다. 방문 목록을 잠그고 다시 GIL 문제가 발생하게됩니다).

(예, 다음 번에 질문을 편집 해주십시오. "멀티 프로세싱"을 보자 마자 문제가 될 수 있다는 것을 알고 있었지만 그렇지 않으면 코드를 전혀 보지 않아도 ...)

관련 문제