0

I am try to get diffent instance of one class in mutil-thread, but the id(instance) retuned the same id random, Even if I add sleep time, this still happens, why?

#!/usr/bin/python
# coding=utf-8

import random
import threading

class Foo():
    def __init__(self):
        self.num = random.randrange(10000)

    def __str__(self):
        return "rand num is {}".format(self.num)

def getInatance():
    if lock.acquire():
        f = Foo()
        print(id(f), f)
        lock.release()

lock = threading.Lock()
if __name__ == "__main__":
    for x in range(10):
        th = threading.Thread(target=getInatance)
        th.start()

    for th in threading.enumerate():
        if th is not threading.current_thread():
            th.join()

# 2384808866048 rand num is 357
# 2384808640128 rand num is 7143
# 2384808640128 rand num is 900
# 2384808640128 rand num is 3260
# 2384808640032 rand num is 8161
# 2384808640032 rand num is 8573
# 2384808640080 rand num is 6300
# 2384808640080 rand num is 3476
# 2384808640128 rand num is 8112
# 2384808640128 rand num is 7357
ikool
  • 153
  • 1
  • 9
  • The method probably returns faster than a new thread can be initialized, and as a result the runtime ends up reusing the same addresses. Try adding `sleep(1)` before `lock.release()` – Mathias R. Jessen Jul 20 '22 at 12:37
  • 3
    Useful background here: https://stackoverflow.com/questions/53034033/id-getattribute-function-returned-different-value-when-getattr-method-d/53034800 Note: *"The values you get from id are guaranteed to be unique, but only among objects that exist at the same time"* – slothrop Jul 20 '22 at 12:37

1 Answers1

6

id(f) is only guaranteed to give you a unique id amog all objects that are currently alive. But your code is structured so it's quite unlikely that more than one Foo instances are alive at the same time.

Your getInatance() function serializes creating the Foo instances, and once the getInatance() function returns, the Foo instance you created is destroyed, and the next object you create may get the same id as a prior object that doesn't exist any more.

If you add a sleep() as shown below you are more likely to see unique object IDs. (But still no guarantees - and remember that adding sleep() to fix apparent multithreading problems is wrong).

def getInatance():
    if lock.acquire():
        f = Foo()
        print(id(f), f)
        lock.release()
    time.sleep(1)
nos
  • 223,662
  • 58
  • 417
  • 506