LINUX.ORG.RU

вопрос про python3


0

1

давно хочу выяснить одну мелочь

вот допустим есть класс:


class Video():
     # код класса

class Test():

     def start(self):
      # запускаем 10 тредов, в качестве воркера self.thread_body

    def thread_body(self, arg):
 
        self.video = Video()
   

вот собственно вопрос - потокобезопасно ли ставить объект video в self? я распечатывал self.video и адреса памяти в каждом потоке были разные

но фактически могут быть какие-то проблемы, self ведь один для всех потоков?

или же каждый поток создает копию всех данных в self? но тогда как работают например общие словари, типа self.data так что все потоки имеют доступ к такому словарю и видят изменения, внесенные другими потоками

я распечатывал self.video и адреса памяти в каждом потоке были разные

self.video = something
print(self.video)

? ))))

Смотри threading.local

baverman ★★★
()

потокобезопасно ли ставить объект video в self?

Смотря чего Вы хотите. Если хранить последний созданный каким то из потоков экземпляр Video - то это как раз оно и будет, но он будет один на все потоки;-)

AIv ★★★★★
()
Ответ на: комментарий от sergey-novikov

хотя все равно непонятно

так что ли делать?

self.mydata = threading.local()
self.mydata.video = Video()

и не станет ли пересекаться self.mydata с такими же в других потоках?

а если self вообще не использовать, то чем она лучше обычной переменной??
тем что в неё можно помещать разные переменные как в объект?

sergey-novikov ★★★
() автор топика
Ответ на: комментарий от sergey-novikov

какая в нем необходимость?

Я так понимаю это нужно для правильной работы таких штук, как super и isinstance, например.

Bad_ptr ★★★★★
()
Ответ на: комментарий от Bad_ptr

Я так понимаю это нужно для правильной работы таких штук, как super и isinstance, например.

В Python3 все классы наследуются от object, его не нужно указывать.

P.S. и не нужно лезть в топик о Python, если ты им не пользуешься.

tailgunner ★★★★★
()

Ты лучше расскажи, что имеешь в виду под потокобезопасностью.

baverman ★★★
()
Ответ на: комментарий от sergey-novikov

а если self вообще не использовать, то чем она лучше обычной переменной??

А зачем тебе self в данном случае? Хочешь разные данные для разных потоков - делай обычную переменную.

anonymous
()
Ответ на: комментарий от tailgunner

В Python3 все классы наследуются от object, его не нужно указывать.

Точно, значит это нужно для совместимости с питоном2. :)

не нужно лезть в топик о Python, если ты им не пользуешься.

Справедливо, но я может быть и полезу, только ради того, чтобы пришёл ты или кто-то другой и разъяснил :).

Bad_ptr ★★★★★
()
Ответ на: комментарий от Bad_ptr

А зачем тебе self в данном случае? Хочешь разные данные для разных потоков - делай обычную переменную.

ну так чтобы не передавать из метода в метод:

video = Video()
self.action(video, data)
...

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

кто-нибудь знает чем всё-таки является self в данном случае?
почему одни данные self.data - являются общими для всех потоков
а объекты типа self.video = Video() - являются разными, расположенными по разным адресам памяти?

sergey-novikov ★★★
() автор топика
Ответ на: комментарий от sergey-novikov

кто-нибудь знает чем всё-таки является self в данном случае?

Ну по логике self это ссылка, такчто сам self и всё, до чего ты через self пытаешься добраться — общее для всех потоков.

а объекты типа self.video = Video() - являются разными, расположенными по разным адресам памяти?

self.video — общая для всех потоков переменная, а вот объект Video() — в каждом потоке создаёться разный, таким образом ты в каждом потоке создаёшь новый объект Video() и затираешь им старое значение, общей для всех потоков, переменной self.video .

Bad_ptr ★★★★★
()
Ответ на: комментарий от Bad_ptr

провел маленький тест на питон 3.2

код:
http://pastebin.com/wB1EPMFk

результаты:

#0 __main__.myClass object at 0xb74e59cc 0
#1 __main__.myClass object at 0xb74e562c 0
#2 __main__.myClass object at 0xb74e586c 0
#3 __main__.myClass object at 0xb74e59cc 0
#4 __main__.myClass object at 0xb74e5dac 0
#5 __main__.myClass object at 0xb74e5b0c 0
#6 __main__.myClass object at 0xb74e82cc 0
#7 __main__.myClass object at 0xb74e5c4c 0
#8 __main__.myClass object at 0xb74e880c 0
#9 __main__.myClass object at 0xb74e5eac 0

адреса разные, но повторяются, как например 0xb74e59cc - потоки #0 и #3

на моем фрейме тот же пример вообще выдает адреса

#5 include.mod.myClass object at 0x9ae1c6c 0
#6 include.mod.myClass object at 0x9ae18cc 0
#7 include.mod.myClass object at 0x9ae1c6c 0
#8 include.mod.myClass object at 0x9ae18cc 0
#9 include.mod.myClass object at 0x9ae1c6c 0

повторяются через 1!
может он медленнее их запускает в силу своего размера, хз


Второй вариант - с рандомной задержкой в потоке.
http://pastebin.com/jCD9TRNu

#0 __main__.myClass object at 0xb752bfec 2
#1 __main__.myClass object at 0xb752bbcc 2
#6 __main__.myClass object at 0xb752eeec 2
#7 __main__.myClass object at 0xb752ec6c 2
#8 __main__.myClass object at 0xb75314ac 2
#2 __main__.myClass object at 0xb752ef2c 2
#9 __main__.myClass object at 0xb752ef2c 3
#3 __main__.myClass object at 0xb752ef2c 4
#4 __main__.myClass object at 0xb752ef2c 5
#5 __main__.myClass object at 0xb752ef2c 6

т.е. 100% self. все портит
адреса почти все одинаковые

а на фрейме адреса повторяются, но значение одинаковое о_О

#0 include.mod.myClass object at 0x93368ec 2
#1 include.mod.myClass object at 0x96a9d4c 2
#2 include.mod.myClass object at 0x93368ec 2
#3 include.mod.myClass object at 0x96a9fac 2
#4 include.mod.myClass object at 0x93368ec 2
#5 include.mod.myClass object at 0x96a9fac 2
#6 include.mod.myClass object at 0x93368ec 2
#7 include.mod.myClass object at 0x96a9fac 2
#8 include.mod.myClass object at 0x93368ec 2
#9 include.mod.myClass object at 0x96a9fac 2

и напоследок простой тестовый скрипт без задержек, но с инкрементом:

#0 __main__.myClass object at 0xb748cfec 2
#1 __main__.myClass object at 0xb748cbcc 2
#2 __main__.myClass object at 0xb748cdec 2
#3 __main__.myClass object at 0xb748cfec 2
#4 __main__.myClass object at 0xb748f60c 2
#5 __main__.myClass object at 0xb748cd2c 2
#6 __main__.myClass object at 0xb748fbac 2
#7 __main__.myClass object at 0xb748cb0c 2
#8 __main__.myClass object at 0xb749216c 2
#9 __main__.myClass object at 0xb748f74c 2

sergey-novikov ★★★
() автор топика
Ответ на: комментарий от baverman

ясно
а вот добавляем threading.local() - http://pastebin.com/uB9H4N5m

если поставить его в self - self.local.t = myClass()

то всего 1 поток выводит свои данные! (а иногда 2 или 3)

как тут замешан сборщик мусора? почему потоки ничего не выводят?

если сделать без self. то всё в порядке, но тогда не вижу вообще смысла в этом local, кроме как передавать в нём данные как в словаре

sergey-novikov ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.