Столкновение памяти процесса метода класса на обработчике sigterm - PullRequest
1 голос
/ 07 февраля 2020

Давайте посмотрим на следующий фрагмент кода:

import multiprocessing as mp
import time
import signal
import os
import sys

class Name:
    def __init__(self, name):
        self.name = name
        print("init {} -> name:{} obj:{}".format(self.name, hex(id(self.name)), hex(id(self))))
        signal.signal(signal.SIGTERM, self.sigterm_handler)
    def run(self):
        while True:
            print("run {} -> name:{} obj:{}".format(self.name, hex(id(self.name)), hex(id(self))))
            time.sleep(1)
    def sigterm_handler(self, _signo, _stack_frame):
        print("exit {} -> name:{} obj:{}".format(self.name, hex(id(self.name)), hex(id(self))))
        os.kill(os.getpid(), 9)

m1 = Name("alice")
p1 = mp.Process(target=m1.run)

p1.start()
m2 = Name("bob")


time.sleep(2)
p1.terminate()

Вот соответствующий вывод:

init alice -> name:0x7f8ee6036500 obj:0x7f8ee5dc2710
init bob -> name:0x7f8ee5dc2730 obj:0x7f8ee5dc2828
run alice -> name:0x7f8ee6036500 obj:0x7f8ee5dc2710
run alice -> name:0x7f8ee6036500 obj:0x7f8ee5dc2710
exit alice -> name:0x7f8ee6036500 obj:0x7f8ee5dc2710

Теперь давайте начнем p1 сразу после создания m2, например:

m1 = Name("alice")
p1 = mp.Process(target=m1.run)

m2 = Name("bob")
p1.start()

time.sleep(2)
p1.terminate()

Вот что мы получаем:

init alice -> name:0x7fa77c4c5500 obj:0x7fa77c2516d8
init bob -> name:0x7fa77c2516f8 obj:0x7fa77c2517b8
run alice -> name:0x7fa77c4c5500 obj:0x7fa77c2516d8
run alice -> name:0x7fa77c4c5500 obj:0x7fa77c2516d8
exit bob -> name:0x7fa77c2516f8 obj:0x7fa77c2517b8

Важно отметить, что последняя строка изменилась с alice до bob. Кажется, что sigterm_handler заменяется на экземпляр из нового экземпляра класса, но это не так с run.

Почему это так?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...