Найти - Пользователи
Полная версия: threading join()
Начало » Python для экспертов » threading join()
1
Basilij
Помогите, пожалуйста, разобраться с join(), который “должен дождаться завершения порожденных потоков и не дать программе завершиться до того, пока хотя бы один обычный поток выполнения продолжает работу.”

По идее в ниже приведенном примере вывод должен быть -
Завершение Thread_002
Завершение Thread_001
Завершение Base
т.е. Base должен завершитья последним, но вместо этого он завершается первым, т.е. join() не дожидается завершения. Почему?

 # -*- coding: UTF-8 -*-
from multiprocessing import Pipe
from threading import Thread
EXIT = 0
class Base(object):
    def __init__(self):
        pipe, self.pipe_001 = Pipe()
        self.Thread_001 = Thread_001(pipe)
        self.Thread_001.start()
    def run(self):
        self.pipe_001.send(EXIT)
        self.Thread_001.join()
    def __del__(self):
        print('Завершение Base')
class Thread_001(Thread):
    def __init__(self, pipe):
        Thread.__init__(self)
        self.pipe = pipe
        pipe, self.pipe_002 = Pipe()
        self.Thread_002 = Thread_002(pipe)
        self.Thread_002.start()
    def run(self):
        command = None
        while command != EXIT:
            command = self.pipe.recv()
        self.pipe_002.send(EXIT)
        self.Thread_002.join()
    def __del__(self):
        print('Завершение Thread_001')
class Thread_002(Thread):
    def __init__(self, pipe):
        Thread.__init__(self)
        self.pipe = pipe
    def run(self):
        command = None
        while command != EXIT:
            command = self.pipe.recv()
    def __del__(self):
        print('Завершение Thread_002')
if __name__ == '__main__':
    Base().run()
Basilij
Эмм… Вот в таком виде работает правильно. Вопрос несколько изменился, почему в первом случае Base завершается первым, а в этом последним?
 # -*- coding: UTF-8 -*-
from multiprocessing import Pipe
from threading import Thread
EXIT = 0
class Base(object):
    def run(self):
        pipe, pipe_001 = Pipe()
        thread_001 = Thread_001(pipe)
        thread_001.start()
        pipe_001.send(EXIT)
        thread_001.join()
    def __del__(self):
        print('Завершение Base')
class Thread_001(Thread):
    def __init__(self, pipe):
        Thread.__init__(self)
        self.pipe = pipe
    def run(self):
        pipe, pipe_002 = Pipe()
        thread_002 = Thread_002(pipe)
        thread_002.start()
        command = None
        while command != EXIT:
            command = self.pipe.recv()
        pipe_002.send(EXIT)
        thread_002.join()
    def __del__(self):
        print('Завершение Thread_001')
class Thread_002(Thread):
    def __init__(self, pipe):
        Thread.__init__(self)
        self.pipe = pipe
    def run(self):
        command = None
        while command != EXIT:
            command = self.pipe.recv()
    def __del__(self):
        print('Завершение Thread_002')
if __name__ == '__main__':
    Base().run()
Basilij
Ага, разобрался, может кому поможет.
join() ждет не завершения всего потока (если в потоке класс запускается), а только метода run(), на __del__() действия join() не распространяется, если потоков несколько, то del'ы от балды завершаются (по крайней мере мне так показалось).
Soteric
Да, __del__ всегда вызываются от балды, в тот момент, когда это захочется питону. На этот метод лучше не закладываться.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB