현재 Linux에서 실행되는 다소 큰 Python 프로젝트가 있지만 Windows로 확장하려고합니다. 코드를 내 문제를 설명하기 위해 실행할 수있는 전체 예제로 축소했습니다. 두 클래스 인 Parent and Child가 있습니다. 부모가 먼저 초기화 된 로거를 생성하고 할 수있는 아이로 급부상되는 작업 :Windows에서 다중 처리로 파이썬 로깅
리눅스에import logging
import logging.config
import multiprocessing
class Parent(object):
def __init__(self, logconfig):
logging.config.dictConfig(logconfig)
self.logger = logging.getLogger(__name__)
def spawnChild(self):
self.logger.info('One')
c = Child(self.logger)
c.start()
class Child(multiprocessing.Process):
def __init__(self, logger):
multiprocessing.Process.__init__(self)
self.logger = logger
def run(self):
self.logger.info('Two')
if __name__ == '__main__':
p = Parent({
'version':1,
"handlers": {
"console": {
"class": "logging.StreamHandler",
"stream": "ext://sys.stdout"
},
},
"root": {
"level": "DEBUG",
"handlers": [
"console",
]
}
}
)
p.spawnChild()
(특히, 우분투 12.04), 나는 다음 (예상) 출력을 얻을 :
[email protected]:~$ python test.py
One
Two
그러나 (특히, 윈도우 7) 윈도우에서, 그것은 산세 오류와 함께 실패합니다 : 객체가 스레드간에 보낼 때 절인 할 필요가 있으므로
C:\>python test.py
<snip>
pickle.PicklingError: Can't pickle <type 'thread.lock'>: it's not found as thread.lock
문제는 진정한 포크의 윈도우의 부족으로 내려 온다. 그러나 로거는 절인 될 수 없습니다. 나는 아이의 이름으로 산 세척 및 참조를 피하기 위해 __getstate__ 및 __setstate__를 사용하여 시도했다 :
def __getstate__(self):
d = self.__dict__.copy()
if 'logger' in d.keys():
d['logger'] = d['logger'].name
return d
def __setstate__(self, d):
if 'logger' in d.keys():
d['logger'] = logging.getLogger(d['logger'])
self.__dict__.update(d)
이것은 이전과 마찬가지로 리눅스에서 작동, 이제 Windows는 PicklingError 실패하지 않을 것이다. 하지만, 내 출력은 부모입니다 :
C:\>python test.py
One
C:\>
아이가 또는 다른 오류 메시지 "어떤 로거 처리기 '__main__'를 찾을 수 없습니다"불평없이 메시지에도 불구하고, 로거를 사용할 수없는 것 같다. 나는 주변을 둘러 보았고 내 프로그램에 로그인하는 방법을 완전히 재구성 할 수있는 방법이 있지만 분명히 마지막 수단입니다. 나는 분명히 무언가를 놓치고 군중의 지혜가 그것을 나에게 지적 할 수 있기를 바라고있다.
'some_dict.keys()'의 key가 정확히이 검사를 수행하는 잘못된 방법입니다. 그것은 python2에서 O (n) 시간이 걸립니다. 그냥'key in some_dict'를 사용하십시오. 문제에 관해서. 하위 프로세스의 stdout이 다를 수 있으므로 출력을 볼 수 없습니다. 파일 처리기를 추가하고 파일의 출력이 올바른지 확인하십시오. – Bakuriu
테스트를 위해 다른 SO 포스트에서 복사 된 키에 대한 메모를 이해합니다. 내 모든 실제 로깅 파일에서 수행되며 문제가 여전히 발생합니다. stdout은 위 스크립트를 작성하기 위해 테스트하기 쉽습니다. "multi_file_handler"를 사용 : { "클래스": "logging.handlers.RotatingFileHandler" "파일 이름": "output.log" 을} - ","하나 \ nTwo "리눅스에 하나, 같은 문제로 연결 "on windows – user2093082
문제는,''__init__''을 unpickling 할 때 보통 * 호출되지 않을 수 있습니다. 즉, 하위 프로세스가'logging.config.dictConfig (...를 호출하지 않았습니다.)'따라서 기본 구성을 사용할 수도 있습니다. '__setstate__' 메소드를 변경하여 올바른 설정으로'dictConfig'를 호출하고 변경 사항이 있는지 확인하십시오. – Bakuriu