Search code examples
pythonmultithreadingpython-multithreading

Multithreading on object methods in python


I am trying to implement multi threading with oops


class test:
    def printer(self):
        for ctr in range(1000000):
            print("hello")

    def printHi(self):
        for ctr in range(1000000):
            print("hi")
            
if __name__ == "__main__":
    test1 = test()

    t1 = threading.Thread(target=test1.printHi, args=(10,))
    t2 = threading.Thread(target=test1.printer, args=(10,))
    t1.start()
    t2.start()
    print("Done!")

But the test1.printHi is expecting me to pass self

Exception in thread Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.9/threading.py", line 973, in _bootstrap_inner
Thread-2:
Traceback (most recent call last):
  File "/usr/lib/python3.9/threading.py", line 973, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.9/threading.py", line 910, in run
    self.run()
  File "/usr/lib/python3.9/threading.py", line 910, in run
    self._target(*self._args, **self._kwargs)    self._target(*self._args, **self._kwargs)

TypeError: printHi() takes 1 positional argument but 2 were givenTypeError: 
printer() takes 1 positional argument but 2 were given
Done!

After passing self it is not being multi threaded any more It

t1 = threading.Thread(target=test1.printHi())
t2 = threading.Thread(target=test1.printer())
t1.start()
print("next")
t2.start()

Its first printing all hi and then hello at last next is getting printed but when I implement them like functions its working properly they are getting printed at once combined. Whats the right way to implement it properly such that both threads runs simultaneously...


Solution

  • You seem to be passing an extra 10 to the methods; try:

    
    class test:
        def printer(self):
            for ctr in range(10):
                print("hello")
                time.sleep(1)
    
        def printHi(self):
            for ctr in range(10):
                print("hi")
                time.sleep(1)
                
    if __name__ == "__main__":
        test1 = test()
    
        t1 = threading.Thread(target=test1.printHi, args=())
        t2 = threading.Thread(target=test1.printer, args=())
        t1.start()
        t2.start()
        print("Done!")
    

    Or, if you want to keep the parameter, the functions need to accept it:

    
    class test:
        def printer(self, n):
            for ctr in range(10):
                print("hello", n)
                time.sleep(1)
    
        def printHi(self, n):
            for ctr in range(10):
                print("hi", n)
                time.sleep(1)
                
    if __name__ == "__main__":
        test1 = test()
    
        t1 = threading.Thread(target=test1.printHi, args=(10,))
        t2 = threading.Thread(target=test1.printer, args=(10,))
        t1.start()
        t2.start()
        print("Done!")