python / python/cpython

multiprocessing.Pool gets stuck indefinitely when the child process is killed manually

Aberta
#96,062 11 comentários 6 reações 0 responsáveis Ver no GitHub

Ninguém assumiu esta issue ainda.

topic-multiprocessing type-bug
Linguagem predominante
Python
Estrelas
77.2k
Forks
36k
Métricas de merge de PRs
Métricas de PR pendentes

Descrição

Bug report

When I use multiprocessing.Pool and let processes=1 to execute the task, if I manually kill the child process in the background, the task will not be executed, and the new child process seems to be waiting indefinitely and cannot be terminated.
Here is the example I tested:

import logging
import multiprocessing
import platform
import time
from multiprocessing import Pool

multiprocessing.log_to_stderr().setLevel(logging.DEBUG)


def print_some(i):
    print("Current process name is %s" % multiprocessing.current_process())
    print("--------------"+str(i)+"--------------")
    return "return "+str(i)


def callback_func(n):
    print (n)


if __name__ == "__main__":
    print(platform.python_version())
    multiprocessing.set_start_method('fork')
    p = Pool(1)
    i = 0
    print(p._pool[0].pid)
    while i < 6:
        p.apply_async(print_some, (i, ), callback=callback_func)
        time.sleep(3)
        i = i+1
    print("end")
    print(p._pool[0].pid)
    p.terminate()
    print("close")

and the output is(I manually kill the process 30995):

3.8.2
[DEBUG/MainProcess] created semlock with handle 6
[DEBUG/MainProcess] created semlock with handle 7
[DEBUG/MainProcess] created semlock with handle 10
[DEBUG/MainProcess] created semlock with handle 11
[DEBUG/MainProcess] created semlock with handle 14
[DEBUG/MainProcess] created semlock with handle 15
[DEBUG/MainProcess] added worker
[INFO/ForkPoolWorker-1] child process calling self.run()
30995
Current process name is <ForkProcess name='ForkPoolWorker-1' parent=30994 started daemon>
--------------0--------------
return 0
Current process name is <ForkProcess name='ForkPoolWorker-1' parent=30994 started daemon>
--------------1--------------
return 1
Current process name is <ForkProcess name='ForkPoolWorker-1' parent=30994 started daemon>
--------------2--------------
return 2
Current process name is <ForkProcess name='ForkPoolWorker-1' parent=30994 started daemon>
--------------3--------------
return 3
[DEBUG/MainProcess] cleaning up worker 0
[DEBUG/MainProcess] added worker
[INFO/ForkPoolWorker-2] child process calling self.run()
[DEBUG/MainProcess] terminating pool
[DEBUG/MainProcess] finalizing pool
[DEBUG/MainProcess] helping task handler/workers to finish
[DEBUG/MainProcess] removing tasks from inqueue until task handler finished
[DEBUG/MainProcess] worker handler exiting
[DEBUG/MainProcess] task handler got sentinel
[DEBUG/MainProcess] task handler sending sentinel to result handler
[DEBUG/MainProcess] task handler sending sentinel to workers
[DEBUG/MainProcess] task handler exiting
[DEBUG/MainProcess] result handler got sentinel
end
31000

From the output, when I kill the child process, multiprocessing.Pool does start a new process, but the task cannot continue, and terminate() seems to be stuck somewhere, because my main process is not over, been waiting.
During the running process of the service, the process of crashing is unpredictable, so I did such a test: when using multi-process, what effect will the child process crash have on the program. Finally found such a problem.

Your environment

  • CPython versions tested on: Python3.8.2
  • Operating system and architecture:MacOS10.15.7 or ubuntu16.0.4

Guia de contribuição

Abrir o guia de contribuição

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Direção de pesquisa

Comece pelo comportamento de multiprocessing.Pool mostrado no reproducer, usando os ambientes Python 3.8.2 relatados no macOS ou Ubuntu. Execute o exemplo novamente enquanto encerra o worker e, em seguida, rastreie a substituição do worker e o tratamento de terminate(). Está concluído quando a tarefa enfileirada pode prosseguir depois que um worker é encerrado e a terminação do pool não espera indefinidamente.

Escrita pelo modelo de indexação a partir do texto da issue.

Avaliação

Stack de tecnologia
python
Domínio
operating-systems
Tipo de issue
Bug
Dificuldade
4/5
Tempo estimado
3-5 dias
Status de atividade
Estagnada
Clareza
Razoavelmente clara
Facilidade para iniciantes
35/100

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.