다중 처리로 인해 Python이 충돌하고 fork()가 호출되었을 때 다른 스레드에서 진행 중이었을 수 있는 오류가 발생합니다.
저는 파이썬이 비교적 생소하며 for 루프를 위해 멀티프로세싱 모듈을 구현하려고 합니다.
Google 비전을 다운로드하여 적용해야 하는 img_urls에 저장된 Imageurl 배열이 있습니다.
if __name__ == '__main__':
img_urls = [ALL_MY_Image_URLS]
runAll(img_urls)
print("--- %s seconds ---" % (time.time() - start_time))
이것은 myrunAll() 메서드입니다.
def runAll(img_urls):
num_cores = multiprocessing.cpu_count()
print("Image URLS {}",len(img_urls))
if len(img_urls) > 2:
numberOfImages = 0
else:
numberOfImages = 1
start_timeProcess = time.time()
pool = multiprocessing.Pool()
pool.map(annotate,img_urls)
end_timeProcess = time.time()
print('\n Time to complete ', end_timeProcess-start_timeProcess)
print(full_matching_pages)
def annotate(img_path):
file = requests.get(img_path).content
print("file is",file)
"""Returns web annotations given the path to an image."""
print('Process Working under ',os.getpid())
image = types.Image(content=file)
web_detection = vision_client.web_detection(image=image).web_detection
report(web_detection)
내가 그것을 실행하고 파이썬이 충돌할 때 경고로 이것을 받고 있습니다.
objc[67570]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called.
objc[67570]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.
objc[67567]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called.
objc[67567]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.
objc[67568]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called.
objc[67568]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.
objc[67569]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called.
objc[67569]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.
objc[67571]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called.
objc[67571]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.
objc[67572]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called.
objc[67572]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.
이 오류는 macOS High Sierra 이상 버전의 macOS에서 멀티스레딩을 제한하는 보안이 추가되었기 때문에 발생합니다.이 답변이 조금 늦은 것은 알지만 다음 방법을 사용하여 문제를 해결했습니다.
환경 변수 설정.bash_profile
(또는).zshrc
최신 macOS의 경우)를 사용하여 새 macOS High Sierra 보안 규칙에서 멀티스레딩 응용 프로그램 또는 스크립트를 허용합니다.
터미널 열기:
$ nano .bash_profile
파일 끝에 다음 행을 추가합니다.
OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
저장하고 종료한 후 터미널을 닫고 다시 엽니다.이제 환경 변수가 설정되었는지 확인합니다.
$ env
다음과 유사한 출력이 표시됩니다.
TERM_PROGRAM=Apple_Terminal
SHELL=/bin/bash
TERM=xterm-256color
TMPDIR=/var/folders/pn/vasdlj3ojO#OOas4dasdffJq/T/
Apple_PubSub_Socket_Render=/private/tmp/com.apple.launchd.E7qLFJDSo/Render
TERM_PROGRAM_VERSION=404
TERM_SESSION_ID=NONE
OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
이제 멀티스레딩으로 Python 스크립트를 실행할 수 있습니다.
다른 대답들은 당신에게 설정하라고 말하고 있습니다.OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
하지만 이러지 마!당신은 그저 경고 신호에 끈적끈적한 테이프를 붙이고 있을 뿐입니다.일부 레거시 소프트웨어에 대해 케이스 바이 케이스로 필요할 수 있지만 이를 설정하지 마십시오..bash_profile
!
이것은 https://bugs.python.org/issue33725 (3.8+)에서 수정되었지만 사용하는 것이 가장 좋습니다.
with multiprocessing.get_context("spawn").Pool() as pool:
pool.map(annotate,img_urls)
MAC 및 z-shell을 실행하고 .zshrc 파일에 다음을 추가해야 했습니다.
export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
다음 명령행에 표시됩니다.
source ~/.zshrc
그 후 효과가 있었습니다.
그OBJC_DISABLE_INITIALIZE_FORK_SAFETY = YES
해결책은 저에게 효과가 없었습니다.또 다른 잠재적인 해결책은 설정입니다.no_proxy = *
스크립트 환경에서 사용할 수 있습니다.
다른 사람들이 다루는 원인 외에도 이 오류 메시지는 네트워킹과 관련이 있을 수 있습니다.내 스크립트에는 tcp 서버가 있습니다.수영장도 안 써요, 그냥.os.fork
그리고.multiprocessing.Queue
메시지 전달용입니다.줄을 추가하기 전까지는 포크가 잘 작동했습니다.
no_proxy 설정 자체가 제 경우에 수정되었습니다.스크립트에 네트워킹 구성 요소가 있는 경우 이 수정 프로그램을 사용해 보십시오.OBJC_DISABLE_INITIALIZE_FORK_SAFETY
.
필요 없이 사용할 수 있습니다.OBJC_DISABLE_INITIALIZE_FORK_SAFETY
환경의 플래그는 초기화를 포함합니다.multiprocessing.Pool
수업이 끝나자마자main()
프로그램이 시작됩니다.
되기 전에 프로세스를 미리 해도 결과가 .... may have been in progress in another thread when fork() was called
병렬화되지 않은 코드에 비해 오류가 발생하고 성능이 크게 향상됩니다.
의 교실을 .Parallelizer
매우 일찍 시작하여 프로그램의 라이프사이클 전체에 걸쳐 사용하고 있습니다.전체 버전은 여기에서 확인할 수 있습니다.
# entry point to my program
def main():
parallelizer = Parallelizer()
...
그런 다음 병렬화를 원할 때마다:
# this function is parallelized. it is run by each child process.
def processing_function(input):
...
return output
...
inputs = [...]
results = parallelizer.map(
inputs,
processing_function
)
그리고 병렬화기 클래스:
class Parallelizer:
def __init__(self):
self.input_queue = multiprocessing.Queue()
self.output_queue = multiprocessing.Queue()
self.pool = multiprocessing.Pool(multiprocessing.cpu_count(),
Parallelizer._run,
(self.input_queue, self.output_queue,))
def map(self, contents, processing_func):
size = 0
for content in contents:
self.input_queue.put((content, processing_func))
size += 1
results = []
while size > 0:
result = self.output_queue.get(block=True)
results.append(result)
size -= 1
return results
@staticmethod
def _run(input_queue, output_queue):
while True:
content, processing_func = input_queue.get(block=True)
result = processing_func(content)
output_queue.put(result)
한 가지 주의할 점: 병렬화된 코드는 디버깅하기 어려울 수 있으므로 하위 프로세스에서 문제가 발생할 때 활성화하는 병렬화되지 않은 버전의 클래스도 준비했습니다.
class NullParallelizer:
@staticmethod
def map(contents, processing_func):
results = []
for content in contents:
results.append(processing_func(content))
return results
언급URL : https://stackoverflow.com/questions/50168647/multiprocessing-causes-python-to-crash-and-gives-an-error-may-have-been-in-progr
'programing' 카테고리의 다른 글
Postgre는 어디에 있습니까?SQL 저장소 구성/conf 파일? (0) | 2023.05.27 |
---|---|
날짜 대 날짜 시간 (0) | 2023.05.27 |
C#과 VB.NET의 가장 중요한 기능적 차이점은 무엇입니까? (0) | 2023.05.27 |
분기를 전환하지 않고 '깃 풀'하는 방법(깃 체크아웃)? (0) | 2023.05.27 |
NodeJS 및 NPM을 최신 버전으로 업데이트하려면 어떻게 해야 합니까? (0) | 2023.05.27 |