1

I'm trying to learn about threading on Python 3. I made an example code:

import time 
import threading

def myfunction(string,sleeptime,lock,*args):
  count = 0
  while count < 2:
    #entering critical section
    lock.acquire()
    print(string, " Now sleeping after Lock acquired for ",sleeptime)
    time.sleep(sleeptime)
    print(string, " Now releasing lock and sleeping again.\n",time.ctime(time.time()))
    lock.release()
    #exiting critical section
    time.sleep(sleeptime)
    count+=1
    #threading.Thread.daemon=True

if __name__!="__main__":
  lock = threading.Lock()
  try:
    threading.Thread.start(myfunction("Thread Nº 1",2,lock))
    threading.Thread.start(myfunction("Thread Nº 2",2,lock))
  except:
    raise

  while 1:pass

It works in part. When it reaches the while<2 loop, it returns the error:

Traceback (most recent call last):
  File "python", line 22, in <module>
AttributeError: 'NoneType' object has no attribute '_initialized'

And never executes the second thread call.

What can I do to correct this?

Thank you all!

4
  • __name__ != "__main__" doesn't look correct at all. Usually the condition is reversed... Commented Jun 26, 2017 at 14:36
  • .. i.e. __name__ == '__main__' Commented Jun 26, 2017 at 14:53
  • Thank you @antti-haapala, but I'm running a web Python interpreter... so the name = builtins, not main.... I've already removed this verification. Commented Jun 26, 2017 at 17:40
  • ah, that's bad :D Commented Jun 26, 2017 at 19:21

1 Answer 1

5

You're using the Thread completely incorrectly. First of all, you're not calling the Thread constructor (i.e. your code must have threading.Thread(<something>) to create new Thread instances). Secondly, you're calling the myfunction with arguments in the main thread, not in a new thread. Third, the return value of that function (the implicit None) is passed as the implicit self argument to the unbound Thread.start method!

The proper way to do it would be

t1 = threading.Thread(target=myfunction, args=("Thread Nº 1", 2, lock))
t1.start()

Likewise for t2. Additionally, if you do it like this, you will retain references to the Thread objects, and you can replace the while 1: pass with

t1.join()
t2.join()
print("Both threads exited, exiting.")

Or equally:

for t in [t1, t2]:
    t.join()
print("Both threads exited, exiting.")

With these modifications, the program will output

Thread Nº 1  Now sleeping after Lock acquired for  2
Thread Nº 1  Now releasing lock and sleeping again.
 Mon Jun 26 17:42:32 2017
Thread Nº 2  Now sleeping after Lock acquired for  2
Thread Nº 2  Now releasing lock and sleeping again.
 Mon Jun 26 17:42:34 2017
Thread Nº 1  Now sleeping after Lock acquired for  2
Thread Nº 1  Now releasing lock and sleeping again.
 Mon Jun 26 17:42:36 2017
Thread Nº 2  Now sleeping after Lock acquired for  2
Thread Nº 2  Now releasing lock and sleeping again.
 Mon Jun 26 17:42:38 2017
Both threads exited, exiting.
Sign up to request clarification or add additional context in comments.

4 Comments

You may also want to mention using t1.join() rather than while 1: pass
Ah, sorry, jumped the gun. Good answer.
I made those changes, but now the "myfunction" funcition doesn't run... It jumps to the "Both threads exited, exiting." message. if __name__!="__main__": lock = threading.Lock() t1 = threading.Thread(target="myfunction",args=("Thread Nº 1",2,lock)) t2 = threading.Thread(target="myfunction",args=("Thread Nº 2",3,lock)) t1.start() t2.start() t1.join() t2.join() print("All threads exited, exiting...")
I found my error! It is not target="myfunction" but target=myfunction. Thanks a lot, @Antti-Haapala!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.