Python threading模块
2种调用方式
直接调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
import
threading
import
time
def
sayhi(num):
#定义每个线程要运行的函数
print
(
"running on number:%s"
%
num)
time.sleep(
3
)
if
__name__
=
=
'__main__'
:
t1
=
threading.Thread(target
=
sayhi,args
=
(
1
,))
#生成一个线程实例
t2
=
threading.Thread(target
=
sayhi,args
=
(
2
,))
#生成另一个线程实例
t1.start()
#启动线程
t2.start()
#启动另一个线程
print
(t1.getName())
#获取线程名
print
(t2.getName())
|
继承式调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
import
threading
import
time
class
MyThread(threading.Thread):
def
__init__(
self
,num):
threading.Thread.__init__(
self
)
self
.num
=
num
def
run(
self
):
#定义每个线程要运行的函数
print
(
"running on number:%s"
%
self
.num)
time.sleep(
3
)
if
__name__
=
=
'__main__'
:
t1
=
MyThread(
1
)
t2
=
MyThread(
2
)
t1.start()
t2.start()
|
第二种有点傻
基本语法
is_alive() 当前活跃的线程
例子:
car1 = threading.Thread(target=car,args=('bmw',)) car1.start() print(car1.is_alive()) if car1.is_alive(): print('33') if not car1.is_alive(): print('444')
执行结果:
bmw wait red light
True
33
例子对比:
car1 = threading.Thread(target=car,args=('bmw',)) # car1.start() 注释掉 print(car1.is_alive()) if car1.is_alive(): print('33') if not car1.is_alive(): print('444')
执行结果:
False
444
Join ()
等待!其实就wait()。
等待该线程执行完毕
Daemon()
守护进程!有句话怎么说来着!守护进程被吞噬!
# _*_coding:utf-8_*_ import time import threading start_time=time.time() def run(n): print('[%s]------running----\n' % n) time.sleep(2) print('--done--%s'%n) def run2(n): print('[%s]------running----\n' % n) time.sleep(5) print('--done--%s'%n) lis_1=[] t1 = threading.Thread(target=run, args=('run%1',)) t2 = threading.Thread(target=run2, args=('run%2',)) lis_1.append(t1) lis_1.append(t2) # t2.setDaemon(True)# 将main线程设置为Daemon线程,它做为程序主线程的守护线程,当主线程退出时,m线程也会退出,由m启动的其它子线程会同时退出,不管是否执行完任务 t1.start() t2.start() # 看下就懂了,不懂试一试就想起来了 t1.join() t2.join() print("---end time----",time.time()-start_time)
线程锁(互斥锁Mutex)
lock()
为什么上锁?因为好多线程同时修改一个数据,有先后顺序,有的没干完,就被gil了,所以对修改数据的地方加把锁,保证该数据的正确性!
lock
=
threading.Lock()
#生成全局锁
不带锁例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
import
time
import
threading
def
addNum():
global
num
#在每个线程中都获取这个全局变量
print
(
'--get num:'
,num )
time.sleep(
1
)
num
-
=
1
#对此公共变量进行-1操作
num
=
100
#设定一个共享变量
thread_list
=
[]
for
i
in
range
(
100
):
t
=
threading.Thread(target
=
addNum)
t.start()
thread_list.append(t)
for
t
in
thread_list:
#等待所有线程执行完毕
t.join()
print
(
'final num:'
, num )
|
带锁例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
import
time
import
threading
def
addNum():
global
num
#在每个线程中都获取这个全局变量
print
(
'--get num:'
,num )
time.sleep(
1
)
lock.acquire()
#修改数据前加锁
num
-
=
1
#对此公共变量进行-1操作
lock.release()
#修改后释放
num
=
100
#设定一个共享变量
thread_list
=
[]
lock
=
threading.Lock()
#生成全局锁
for
i
in
range
(
100
):
t
=
threading.Thread(target
=
addNum)
t.start()
thread_list.append(t)
for
t
in
thread_list:
#等待所有线程执行完毕
t.join()
print
(
'final num:'
, num )
|
RLock(递归锁)
这个主要针对函数甲里边包涵函数乙,函数乙又有函数丙
绕进去了,很麻烦,用lock的话容易死循环,所以用Rlock,一键上锁,保证不乱。例子看看就好。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
import
threading,time
def
run1():
print
(
"grab the first part data"
)
lock.acquire()
global
num
num
+
=
1
lock.release()
return
num
def
run2():
print
(
"grab the second part data"
)
lock.acquire()
global
num2
num2
+
=
1
lock.release()
return
num2
def
run3():
lock.acquire()
res
=
run1()
print
(
'--------between run1 and run2-----'
)
res2
=
run2()
lock.release()
print
(res,res2)
if
__name__
=
=
'__main__'
:
num,num2
=
0
,
0
lock
=
threading.RLock()
for
i
in
range
(
10
):
t
=
threading.Thread(target
=
run3)
t.start()
while
threading.active_count() !
=
1
:
print
(threading.active_count())
else
:
print
(
'----all threads done---'
)
print
(num,num2)
|
Semaphore(信号量)
互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据 ,比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去。
例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
import
threading,time
def
run(n):
semaphore.acquire()
time.sleep(
1
)
print
(
"run the thread: %s\n"
%
n)
semaphore.release()
if
__name__
=
=
'__main__'
:
num
=
0
semaphore
=
threading.BoundedSemaphore(
5
)
#最多允许5个线程同时运行
for
i
in
range
(
20
):
t
=
threading.Thread(target
=
run,args
=
(i,))
t.start()
while
threading.active_count() !
=
1
:
pass
#print threading.active_count()
else
:
print
(
'----all threads done---'
)
print
(num)
|
Events
重点,标识符,event可以理解成对全局变量不停的修改,!!!!!!这个我感觉后边能用的到,用event来验证result
语法有
event = threading.Event()
创建标识符
event.set( )
设置标识符
event.wait( )
等待标识符出现,一旦出现立刻执行后边的代码
print(‘杀啊!!’) event.wait() print( ‘撤退!!,杀个瘠薄’
event.clear( )
清空标志位
通过Event来实现两个或多个线程间的交互
红绿灯例子!!
import time import threading event=threading.Event() def car(name): while True: if event.is_set(): print('%s is runing'%name) time.sleep(1) else: print('%s wait red light' % name) event.wait() time.sleep(1) def light(): conent = 0 event.set() while True: if conent >5 and conent <10: event.clear() print('\033[41;1mred light is on ....\033[0m') elif conent >10: event.set() conent = 0 else: print('\033[42;1mgreen is come!\033[0m') time.sleep(1) conent += 1 light = threading.Thread(target=light,) car2 = threading.Thread(target=car,args=('tesla',)) car1 = threading.Thread(target=car,args=('bmw',)) light.start() car1.start() car2.start()
运行结果