import threading
import time
def worker1(n:int):
for _ in range(n):
time.sleep(0.5)
print('welcome python')
print('thead over')
def worker2(n:int):
i = 0
while True:
# for _ in range(10):
if i > n:
# break
raise Exception('New Exception')
time.sleep(0.5)
print('welcome python....')
i += 1
print('thead over....')
t = threading.Thread(target=worker1, name='w1',args=(5,))
t.start()
t = threading.Thread(target=worker2, name='w2',kwargs={'n':5})
t.start()
运行结果:
welcome python
welcome python....
welcome python....
welcome python
welcome python
welcome python....
welcome python....
welcome python
welcome python....
welcome python
thead over
welcome python....
Exception in thread w2:
Traceback (most recent call last):
File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
self.run()
File "/usr/lib/python3.5/threading.py", line 862, in run
self._target(*self._args, **self._kwargs)
File "/home/yzx/PycharmProjects/cmdb/thread.py", line 18, in worker2
raise Exception('New Exception')
Exception: New Exception
线程执行顺序:
import threading
import time
def worker1(n=5):
print('sub = ',threading.current_thread())
print('sub main1 = ',threading.main_thread())
for _ in range(n):
time.sleep(0.5)
print('welcome python')
print('sub main2 = ', threading.main_thread())
print('thread over')
print('main1 = ',threading.current_thread())
t = threading.Thread(target=worker1, name='w1')
t.start()
print('main2 = ',threading.current_thread())
运行结果:
/usr/bin/python3.5 /home/yzx/PycharmProjects/cmdb/thread.py
main1 = <_MainThread(MainThread, started 140531765335808)>
sub = <Thread(w1, started 140531741116160)>
sub main1 = <_MainThread(MainThread, started 140531765335808)>
main2 = <_MainThread(MainThread, started 140531765335808)>
welcome python
welcome python
welcome python
welcome python
welcome python
sub main2 = <_MainThread(MainThread, stopped 140531765335808)>
thread over
主线程和子线程
import threading
import time
def worker1(n=5):
print('sub = ',threading.current_thread())
print('sub main1 = ',threading.main_thread())
print('sub thread ID = ', threading.get_ident())
print(threading.active_count())
print('sub thread list = ',threading.enumerate())
for _ in range(n):
time.sleep(0.5)
print('welcome python')
print('sub main2 = ', threading.main_thread())
print('thread over')
print('main1 = ',threading.current_thread())
t = threading.Thread(target=worker1, name='w1')
t.start()
print('main2 = ',threading.current_thread())
print('main thread ID = ',threading.get_ident())
print('main thread list = ',threading.enumerate())
运行结果:
main1 = <_MainThread(MainThread, started 140687047280384)>
main2 = <_MainThread(MainThread, started 140687047280384)>
main thread ID = 140687047280384
main thread list = [<_MainThread(MainThread, started 140687047280384)>, <Thread(w1, started 140687023060736)>]
sub = <Thread(w1, started 140687023060736)>
sub main1 = <_MainThread(MainThread, stopped 140687047280384)>
sub thread ID = 140687023060736
2
sub thread list = [<_MainThread(MainThread, stopped 140687047280384)>, <Thread(w1, started 140687023060736)>]
welcome python
welcome python
welcome python
welcome python
welcome python
sub main2 = <_MainThread(MainThread, stopped 140687047280384)>
thread over
查看进程:
import threading
import time
def showinfo():
print('current thread = {}'.format(threading.current_thread()))
print('main thread = {}'.format(threading.main_thread()))
print('active thread = {}'.format(threading.enumerate()))
print('active thread count = {}'.format(threading.active_count()))
def worker1(n=5):
count = 0
showinfo()
while True:
if count > 5:
break
time.sleep(1)
count += 1
print('I am working')
print('main1 = ', threading.current_thread())
t = threading.Thread(target=worker1, name='w1')
t.start()
运行结果:
main1 = <_MainThread(MainThread, started 139953807304448)>
current thread = <Thread(w1, started 139953783084800)>
main thread = <_MainThread(MainThread, stopped 139953807304448)>
active thread = [<_MainThread(MainThread, stopped 139953807304448)>, <Thread(w1, started 139953783084800)>]
active thread count = 2
I am working
I am working
I am working
I am working
I am working
I am working
start 和 run的区别
import threading
import time
class Mythread(threading.Thread):
def start(self) -> None:
print('start')
super().start()
def run(self) -> None:
print('run')
super().run()
def worker1(n=5):
count = 0
while True:
if count > 5:
break
time.sleep(0.5)
count += 1
print('I am working')
t = Mythread(target=worker1, name='w1')
t.start()
print('====================================')
t = Mythread(target=worker1, name='w2') #由于start只能调用一次,所以需要新生成一个线程才能真正重复
t.start()
# t.run()
运行结果:
start
run
====================================
start
run
I am working
I am working
I am working
I am working
I am working
I am working
I am working
I am working
I am working
I am working
I am working
I am working
线程的安全
import threading
import logging
logging.basicConfig(level=logging.INFO)
def worker1():
for x in range(5):
msg = "{} is running".format(threading.current_thread())
logging.info(msg) # 单独起了一个线程在跑
print(threading.enumerate()) # 这个打印跟上面的输出会交叉输出打印
print('worker1 end')
threading.Thread(target=worker1, name='worker1-{}'.format(0), daemon=False).start()
运行结果:
[<_MainThread(MainThread, stopped 140034083918912)>, <Thread(worker1-0, started 140034061784832)>]
[<_MainThread(MainThread, stopped 140034083918912)>, <Thread(worker1-0, started 140034061784832)>]
INFO:root:<Thread(worker1-0, started 140034061784832)> is running
INFO:root:<Thread(worker1-0, started 140034061784832)> is running
INFO:root:<Thread(worker1-0, started 140034061784832)> is running
INFO:root:<Thread(worker1-0, started 140034061784832)> is running
[<_MainThread(MainThread, stopped 140034083918912)>, <Thread(worker1-0, started 140034061784832)>]
[<_MainThread(MainThread, stopped 140034083918912)>, <Thread(worker1-0, started 140034061784832)>]
[<_MainThread(MainThread, stopped 140034083918912)>, <Thread(worker1-0, started 140034061784832)>]
worker1 end
INFO:root:<Thread(worker1-0, started 140034061784832)> is running
线程的daemon和non daemon
import threading
import logging
logging.basicConfig(level=logging.INFO)
def worker1():
threading.Thread(target=worker2,name='worker2-{}'.format(0),daemon=True).start()
for x in range(5):
msg = "{} is running".format(threading.current_thread())
logging.info(msg) #单独起了一个线程在跑
# print(threading.enumerate()) # 这个打印跟上面的输出会交叉输出打印
print('worker1 end')
def worker2():
for x in range(1000):
msg = "----------{} is running".format(threading.current_thread())
logging.info(msg) #单独起了一个线程在跑
print('worker2 end')
threading.Thread(target=worker1,name='worker1-{}'.format(0),daemon=False).start()
运行结果:
worker1 end
INFO:root:----------<Thread(worker1-0, started daemon 140185261410048)> is running
INFO:root:<Thread(worker1-0, started 140185269802752)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140185261410048)> is running
INFO:root:<Thread(worker1-0, started 140185269802752)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140185261410048)> is running
INFO:root:<Thread(worker1-0, started 140185269802752)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140185261410048)> is running
INFO:root:<Thread(worker1-0, started 140185269802752)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140185261410048)> is running
INFO:root:<Thread(worker1-0, started 140185269802752)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140185261410048)> is running
线程等待和阻塞(join):
import threading
import logging
import time
logging.basicConfig(level=logging.INFO)
def worker1():
for x in range(3):
msg = "{} is running".format(threading.current_thread())
logging.info(msg) # 单独起了一个线程在跑
t = threading.Thread(target=worker2, name='worker1-{}'.format(0), daemon=True)
t.start()
t.join() #worker1要等worker2执行完
print('worker1 end')
def worker2():
for x in range(5):
msg = "----------{} is running".format(threading.current_thread())
logging.info(msg) # 单独起了一个线程在跑
print('worker2 end')
t = threading.Thread(target=worker1, name='worker1-{}'.format(0), daemon=True)
t.start()
t.join() #主线程要等worker1执行完成
print('main end')
运行结果:
INFO:root:<Thread(worker1-0, started daemon 140545885087488)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545876694784)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545876694784)> is running
worker2 end
INFO:root:----------<Thread(worker1-0, started daemon 140545876694784)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545876694784)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545876694784)> is running
INFO:root:<Thread(worker1-0, started daemon 140545885087488)> is running
worker2 end
INFO:root:----------<Thread(worker1-0, started daemon 140545866110720)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545866110720)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545866110720)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545866110720)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545866110720)> is running
INFO:root:<Thread(worker1-0, started daemon 140545885087488)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545866110720)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545866110720)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545866110720)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545866110720)> is running
INFO:root:----------<Thread(worker1-0, started daemon 140545866110720)> is running
worker2 end
worker1 end
main end
线程中的局部变量:
传统:
import threading
import time
class A:
def __init__(self,x):
self.x = x
a = A(0)
def worker():
a.x = 0
for i in range(10):
time.sleep(0.001)
a.x += 1
print(threading.current_thread(),a.x)
for i in range(10):
threading.Thread(target=worker).start()
运行结果:
<Thread(Thread-3, started 140696810497792)> 61
<Thread(Thread-5, started 140696793712384)> 63
<Thread(Thread-4, started 140696802105088)> 64
<Thread(Thread-2, started 140696818890496)> 65
<Thread(Thread-1, started 140696827283200)> 67
<Thread(Thread-6, started 140696785319680)> 71
<Thread(Thread-7, started 140696776926976)> 72
<Thread(Thread-8, started 140696768534272)> 75
<Thread(Thread-9, started 140696283510528)> 76
<Thread(Thread-10, started 140696275117824)> 78
改进:
import threading
import time
a = threading.local()
def worker():
a.x = 0
for i in range(10):
time.sleep(0.001)
a.x += 1
print(threading.get_ident(),a.__dict__)
print(threading.current_thread(),a.x)
for i in range(10):
threading.Thread(target=worker).start()
运行结果:
140359073281792 {'x': 10}
<Thread(Thread-1, started 140359073281792)> 10
140358994360064 {'x': 10}
<Thread(Thread-2, started 140358994360064)> 10
140358985967360 {'x': 10}
<Thread(Thread-3, started 140358985967360)> 10
140358969181952 {'x': 10}
140358977574656 {'x': 10}
<Thread(Thread-5, started 140358969181952)> 10
<Thread(Thread-4, started 140358977574656)> 10
140358960789248 {'x': 10}
<Thread(Thread-6, started 140358960789248)> 10
140358952396544 {'x': 10}
<Thread(Thread-7, started 140358952396544)> 10
140358944003840 {'x': 10}
<Thread(Thread-8, started 140358944003840)> 10
140358457489152 {'x': 10}
<Thread(Thread-9, started 140358457489152)> 10
140358449096448 {'x': 10}
<Thread(Thread-10, started 140358449096448)> 10
线程的延迟和取消
import threading
import time
def add(x, y):
print(x + y)
t = threading.Timer(10, add, args=(4, 5)) #延迟时间
t.start()
time.sleep(2)
t.cancel() #可以放在start前面