Уведомления

Группа в Telegram: @pythonsu

#1 Май 15, 2017 00:05:59

Basilij
Зарегистрирован: 2017-05-14
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

threading join()

Помогите, пожалуйста, разобраться с 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 (Май 15, 2017 00:18:16)

Офлайн

#2 Май 15, 2017 00:20:50

Basilij
Зарегистрирован: 2017-05-14
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

threading join()

Эмм… Вот в таком виде работает правильно. Вопрос несколько изменился, почему в первом случае 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()

Офлайн

#3 Май 17, 2017 15:34:15

Basilij
Зарегистрирован: 2017-05-14
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

threading join()

Ага, разобрался, может кому поможет.
join() ждет не завершения всего потока (если в потоке класс запускается), а только метода run(), на __del__() действия join() не распространяется, если потоков несколько, то del'ы от балды завершаются (по крайней мере мне так показалось).

Офлайн

#4 Май 18, 2017 20:19:56

Soteric
От:
Зарегистрирован: 2010-09-19
Сообщения: 352
Репутация: +  20  -
Профиль   Отправить e-mail  

threading join()

Да, __del__ всегда вызываются от балды, в тот момент, когда это захочется питону. На этот метод лучше не закладываться.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version