python多线程学习笔记

一.多线程相关python包/模块

  1.thread

    该模块有问题,使用不便,在python3中被保留,并且改成了_thread

  2.threading

    python3中通用的多线程包

二.什么是多线程

  案例1:

  无多线程程序代码

 1 import time
 2 
 3 def loop1():
 4     print('loop1 begining:',time.ctime())
 5     time.sleep(4)
 6     print('loop1 ending:',time.ctime())
 7 
 8 def loop2():
 9     print('loop2 begining:',time.ctime())
10     time.sleep(2)
11     print('loop2 ending:',time.ctime())
12 
13 def main():
14     print('main beginging',time.ctime())
15     loop1()
16     loop2()
17     print('main ending',time.ctime())
18 
19 if __name__ == '__main__':
20     main()
main beginging Wed Aug 22 21:33:34 2018
loop1 begining: Wed Aug 22 21:33:34 2018
loop1 ending: Wed Aug 22 21:33:38 2018
loop2 begining: Wed Aug 22 21:33:38 2018
loop2 ending: Wed Aug 22 21:33:40 2018
main ending Wed Aug 22 21:33:40 2018
out1

  案例2:

  含有多线程程序代码1

 1 import time
 2 import _thread as thread
 3 
 4 def loop1():
 5     print('loop1 begining:',time.ctime())
 6     time.sleep(4)
 7     print('loop1 ending:',time.ctime())
 8 
 9 def loop2():
10     print('loop2 begining:',time.ctime())
11     time.sleep(2)
12     print('loop2 ending:',time.ctime())
13 
14 def main():
15     print('main beginging:',time.ctime())
16     thread.start_new_thread(loop1,())
17     thread.start_new_thread(loop2,())
18     print('main ending:',time.ctime())
19 
20 if __name__ == '__main__':
21     main()
main beginging: Wed Aug 22 21:35:07 2018
main ending: Wed Aug 22 21:35:07 2018
out2


启动多线程函数:start_new_thead
参数两个,一个是需要运行的函数名,第二是函数的参数作为元祖使用,为空则使用空元祖
注意:如果函数只有一个参数,需要参数后由一个逗号

 

案例中,main函数执行完,程序立刻退出.loop1,loop2并没有执行完

main函数相当于包工头

loop1,loop2相当于工人

main函数(包工头)分配loop1,loop2(工人)任务之后,立刻报告给boss,没有等loop1,loop2完成各自的任务

  案例3:

  含有多线程程序代码2-改进版

 1 import time
 2 import _thread as thread
 3 
 4 def loop1():
 5     print('loop1 begining:',time.ctime())
 6     time.sleep(4)
 7     print('loop1 ending:',time.ctime())
 8 
 9 def loop2():
10     print('loop2 begining:',time.ctime())
11     time.sleep(2)
12     print('loop2 ending:',time.ctime())
13 
14 def main():
15     print('main beginging:',time.ctime())
16     thread.start_new_thread(loop1,())
17     thread.start_new_thread(loop2,())
18     print('main ending:',time.ctime())
19 
20 if __name__ == '__main__':
21     main()
22     while True:
23         time.sleep(1)
main beginging: Wed Aug 22 21:45:10 2018
main ending: Wed Aug 22 21:45:10 2018
loop1 begining: Wed Aug 22 21:45:10 2018
loop2 begining: Wed Aug 22 21:45:10 2018
loop2 ending: Wed Aug 22 21:45:12 2018
loop1 ending: Wed Aug 22 21:45:14 2018
out3

在改进案例中:

增加while True: // time.sleep()

while True:无限循环

这样就避免了程序在main函数执行完后立刻退出,使得loop1,loop2得以执行

  案例4:

  含有多线程程序代码3-带参数

 1 from time import ctime,sleep
 2 import _thread as thread
 3 
 4 def loop1(x):
 5     print('loop1 begining:',ctime())
 6     sleep(4)
 7     print('LOOP1:I am {0}'.format(x))
 8     print('loop1 ending: ' ,ctime())
 9 
10 def loop2(x,y):
11     print('loop2 begining:',ctime())
12     sleep(2)
13     print('LOOP2:I am {0}\nLOOP2:I am {1}'.format(x,y))
14     print('loop2 ending: ' ,ctime())
15 
16 def main():
17     print('main begining:',ctime())
18     thread.start_new_thread(loop1,('Jone',))
19     thread.start_new_thread(loop2,('Tom','king'))
20     print('main ending: ',ctime())
21 
22 if __name__ == '__main__':
23     main()
24     while True:
25         sleep(1)

 

三.threading模块的使用

   案例1:

 1 import time
 2 import threading
 3 
 4 def loop1(x):
 5     print('loop1 start:',time.ctime())
 6     print('LOOP1:I am ',x)
 7     time.sleep(4)
 8     print('loop1 end:',time.ctime())
 9 
10 def loop2(x,y):
11     print('loop2 start:',time.ctime())
12     print('LOOP2:I am',x)
13     print('LOOP2:I am',y)
14     time.sleep(2)
15     print('loop2 end:',time.ctime())
16 
17 def main():
18     print('main start:',time.ctime())
19     t1 = threading.Thread(target = loop1,args = ('JONE',))
20     t2 = threading.Thread(target = loop2,args = ('KIMI','SUKI'))
21     t1.start()
22     t2.start()
23     print('main end:',time.ctime())
24 if __name__ == '__main__':
25     main()
main start: Wed Aug 22 23:41:38 2018
loop1 start: Wed Aug 22 23:41:38 2018
LOOP1:I am  JONE
loop2 start: Wed Aug 22 23:41:38 2018
LOOP2:I am KIMI
LOOP2:I am SUKI
main end: Wed Aug 22 23:41:38 2018
loop2 end: Wed Aug 22 23:41:40 2018
loop1 end: Wed Aug 22 23:41:42 2018
out1

  案例2:

  join案例

 1 import time
 2 import threading
 3 
 4 def loop1(x):
 5     print('loop1 start:',time.ctime())
 6     print('LOOP1:I am ',x)
 7     time.sleep(4)
 8     print('loop1 end:',time.ctime())
 9 
10 def loop2(x,y):
11     print('loop2 start:',time.ctime())
12     print('LOOP2:I am',x)
13     print('LOOP2:I am',y)
14     time.sleep(2)
15     print('loop2 end:',time.ctime())
16 
17 def main():
18     print('main start:',time.ctime())
19     t1 = threading.Thread(target = loop1,args = ('JONE',))
20     t2 = threading.Thread(target = loop2,args = ('KIMI','SUKI'))
21     t1.start()
22     t2.start()
23 
24     t1.join()
25     t2.join()
26     print('main end:',time.ctime())
27 if __name__ == '__main__':
28     main()
main start: Wed Aug 22 23:44:50 2018
loop1 start: Wed Aug 22 23:44:50 2018
LOOP1:I am  JONE
loop2 start: Wed Aug 22 23:44:50 2018
LOOP2:I am KIMI
LOOP2:I am SUKI
loop2 end: Wed Aug 22 23:44:52 2018
loop1 end: Wed Aug 22 23:44:54 2018
main end: Wed Aug 22 23:44:54 2018
out2

t.start():开始启动多线程 

t.join():等待多线性执行完成

threading.Thread(target = function,args = ())

可以发现,与_thread相比,没有while True 也能正常的执行

threading更为方便

四.守护线程

  案例1:

  无守护线程函数

 1 import threading
 2 import time
 3 
 4 def fun():
 5     print('fun START')
 6     time.sleep(2)
 7     print('fun END')
 8 
 9 t = threading.Thread(target = fun,args = ())
10 t.start()
11 time.sleep(1)
12 print('main END')
fun START
main END
fun END
out1

  案例2:

  存在守护线程函数

 1 import threading
 2 import time
 3 
 4 def fun():
 5     print('fun START')
 6     time.sleep(2)
 7     print('fun END')
 8 
 9 t = threading.Thread(target = fun,args = ())
10 t.setDaemon(True)
11 t.start()
12 time.sleep(1)
13 print('main END')
fun START
main END
out2

 

守护线程:

t.setDaemon(True)

或者

t.daemon = True

守护线程必须在start之前设置

在程序中把子线程设置成守护线程,那么在主线程结束的时候,该子线程也会跟着结束

通常,守护线程不可以离开主线程运行

守护线程,能否成功执行与编程环境有关

五.常用线程属性

1.threading.currentThread:返回当前线程变量

2.threadng.enumerate:返回一个包含正在运行的线程列表

3.threading.activeCount:返回正在运行线程数量,效果与len(threading.enumerate)相同

4.thr.setName:设置线程名字

5.thr.getName:获得线程名字

 

  案例1:

 1 import time
 2 import threading
 3 
 4 def loop1():
 5     print('loop1 start:',time.ctime())
 6     time.sleep(5)
 7     print('loop1 end:',time.ctime())
 8 
 9 def loop2():
10     print('loop2 start:',time.ctime())
11     time.sleep(2)
12     print('loop2 start:',time.ctime())
13 def loop3():
14     print('loop3 start:',time.ctime())
15     time.sleep(1)
16     print('loop3 end:',time.ctime())
17 
18 def main():
19     print('MAIN START:',time.ctime())
20     t1 = threading.Thread(target = loop1,args = ())
21     t2 = threading.Thread(target = loop2,args = ())
22     t3 = threading.Thread(target = loop3,args = ())
23     t1.setName('Thr1')
24     t2.setName('Thr2')
25     t3.setName('Thr3')
26     t1.start()
27     t2.start()
28     t3.start()
29     time.sleep(3)
30     for i in threading.enumerate():
31         print('正在运行的子线程有:',i.getName())
32     print('正在运行的子线程数量是:',threading.activeCount())
33     t1.join()
34     t2.join()
35     t3.join()
36     print('MAIN END:',time.ctime())
37 
38 if __name__ == '__main__':
39     main()
MAIN START: Fri Aug 24 23:27:08 2018
loop1 start: Fri Aug 24 23:27:08 2018
loop2 start: Fri Aug 24 23:27:08 2018
loop3 start: Fri Aug 24 23:27:08 2018
loop3 end: Fri Aug 24 23:27:09 2018
loop2 start: Fri Aug 24 23:27:10 2018
正在运行的子线程有: MainThread
正在运行的子线程有: Thr1
正在运行的子线程数量是: 2
loop1 end: Fri Aug 24 23:27:13 2018
MAIN END: Fri Aug 24 23:27:13 2018
out1

六.线程继承

  案例1:

 1 import threading
 2 import time
 3 
 4 class Thread_My(threading.Thread):
 5     def __init__(self,args):
 6         self.args = args
 7     def run(self):
 8         time.sleep(2)
 9         print('The arg is {0}'.format(self.args))
10         print('The time is {0}'.format(time.ctime()))
11 
12 for i in range(5):
13     t = Thread_My(i)
14     t.start()
15     t.join()
16 
17 print('\nmian loop end',time.ctime())

 

Traceback (most recent call last):
  File "D:/pathon L/全栈/多线程/threading_inherit.py", line 15, in <module>
    t.start()
  File "C:\ProgramData\Anaconda3\lib\threading.py", line 839, in start
    raise RuntimeError("thread.__init__() not called")
RuntimeError: thread.__init__() not called
out1

报错,父类初始化__init__函数没有被调用,不能正常使用父类函数模块

  案例2:

  更改后

 1 import threading
 2 import time
 3 
 4 class Thread_My(threading.Thread):
 5     def __init__(self,args):
 6         super(Thread_My,self).__init__()
 7         self.args = args
 8     def run(self):
 9         time.sleep(2)
10         print('The arg is {0}'.format(self.args))
11         print('The time is {0}'.format(time.ctime()))
12 
13 for i in range(5):
14     t = Thread_My(i)
15     t.start()
16     t.join()
17 
18 print('\nmian loop end',time.ctime())
The arg is 0
The time is Fri Aug 24 23:55:21 2018
The arg is 1
The time is Fri Aug 24 23:55:23 2018
The arg is 2
The time is Fri Aug 24 23:55:25 2018
The arg is 3
The time is Fri Aug 24 23:55:27 2018
The arg is 4
The time is Fri Aug 24 23:55:29 2018

mian loop end Fri Aug 24 23:55:29 2018
out2

Thread_My继承threading.Thread的功能

run函数是原threading.Thread的内置函数

run函数代表真正执行的功能

将run函数改写成符合目的的函数

  案例3:

  继承——工业风

 1 import threading
 2 from time import sleep, ctime
 3 
 4 
 5 
 6 class ThreadFunc:
 7 
 8     def __init__(self, name):
 9         self.name = name
10 
11     def loop(self, nloop, nsec):
12         '''
13         :param nloop: loop函数的名称
14         :param nsec: 系统休眠时间
15         :return:
16         '''
17         print('Start loop ', nloop, 'at ', ctime())
18         sleep(nsec)
19         print('Done loop ', nloop, ' at ', ctime())
20 
21 def main():
22     print("Starting at: ", ctime())
23 
24     # ThreadFunc("loop").loop 跟一下两个式子相等:
25     # t = ThreadFunc("loop")
26     # t.loop
27     # 以下t1 和  t2的定义方式相等
28     t = ThreadFunc("loop")
29     t1 = threading.Thread( target = t.loop, args=("LOOP1", 4))
30     # 下面这种写法更西方人,工业化一点
31     t2 = threading.Thread( target = ThreadFunc('loop').loop, args=("LOOP2", 2))
32 
33     # 常见错误写法
34     #t1 = threading.Thread(target=ThreadFunc('loop').loop(100,4))
35     #t2 = threading.Thread(target=ThreadFunc('loop').loop(100,2))
36 
37     t1.start()
38     t2.start()
39 
40     t1.join( )
41     t2.join()
42 
43 
44     print("ALL done at: ", ctime())
45 
46 
47 if __name__ == '__main__':
48     main()

 七.共享变量问题

  案例1:

 1 import threading
 2 
 3 sum = 0
 4 sumd = 1000000
 5 
 6 def my_Add():
 7     global sum,sumd
 8     for i in range(sumd):
 9         sum += 1
10 
11 def my_Minu():
12     global sum,sumd
13     for i in range(sumd):
14         sum -= 1
15 
16 def main():
17     print('main start:',sum)
18     t1 = threading.Thread(target = my_Add,args = ())
19     t2 = threading.Thread(target = my_Minu,args = ())
20     t1.start()
21     t2.start()
22     t1.join()
23     t2.join()
24     print('main end:',sum)
25 
26 if __name__ == '__main__':
27     main()
main start: 0
main end: 462177
out1

 共享变量在多线程中被同时访问会出现混乱,如案例1

解决方法:锁,信号灯

 

八.锁(lock)

  案例1:

 1 import threading
 2 
 3 sum = 0
 4 sumd = 1000000
 5 lock = threading.Lock()
 6 
 7 def my_Add():
 8     global sum,sumd
 9     for i in range(sumd):
10         lock.acquire()
11         sum += 1
12         lock.release()
13 
14 def my_Minu():
15     global sum,sumd
16     for i in range(sumd):
17         lock.acquire()
18         sum -= 1
19         lock.release()
20 
21 def main():
22     print('main start:',sum)
23     t1 = threading.Thread(target = my_Add,args = ())
24     t2 = threading.Thread(target = my_Minu,args = ())
25     t1.start()
26     t2.start()
27     t1.join()
28     t2.join()
29     print('main end:',sum)
30 
31 if __name__ == '__main__':
32     main()

 锁:标志一个线程在使用该资源

使用方法:

1.上锁:lock.acquire()

2.稳定使用共享资源

3.释放锁:lock.release()

 

九.线程安全问题

如果一个资源/变量在不加锁的情况下也不会引起任何问题,则为线程安全

线程安全变量类型:queue

线程不安全变量类型:list,set,dict...

 

十.生产消费者问题

   案例1:

 1 import threading
 2 import queue
 3 import time
 4 
 5 class Producer(threading.Thread):
 6     def run(self):
 7         global queue
 8         count = 0
 9         while True:
10             if q.qsize() < 1000:
11                 for i in range(100):
12                     count += 1
13                     msg = self.name + '生产产品' + str(count)
14                     q.put(msg)
15                     print(msg)
16             time.sleep(0.5)
17 
18 class Customer(threading.Thread):
19     def run(self):
20         global queue
21         while True:
22             if q.qsize() > 100:
23                 for i in range(3):
24                     msg = self.name + '消费' + q.get()
25                     print(msg)
26             time.sleep(1)
27 
28 
29 if __name__ == '__main__':
30     q = queue.Queue()
31 
32     for i in range(500):
33         q.put('初始产品'+str(i))
34     for i in range(2):
35         p = Producer()
36         p.start()
37     for i in range(5):
38         c = Customer()
39         c.start()

queue为用来存放变量的数据结构

特点:先进先出

可视为特殊的列表

q = queue.Queue()

q.qsize():返回q内容长度

q.put():在q中放入数据

q.get():在q中获得数据

 

十一.死锁问题

 1 import threading
 2 import time
 3 
 4 l1 = threading.Lock()
 5 l2 = threading.Lock()
 6 
 7 def fun1():
 8     l1.acquire()
 9     print('fun1 申请了 l1......')
10     time.sleep(2)
11     print('fun1 等待l2......')
12     l2.acquire()
13     print('fun1 申请了 l2......')
14     l1.release()
15     print('fun1 释放了 ll......')
16     l2.release()
17     print('fun1 释放了 l2......')
18 
19 def fun2():
20     l2.acquire()
21     print('fun2 申请了 l2......')
22     time.sleep(4)
23     print('fun2 等待l1......')
24     l1.acquire()
25     print('fun2 申请了 l1......')
26     l2.release()
27     print('fun2 释放了 l2......')
28     l1.release()
29     print('fun2 释放了 l1')
30 
31 if __name__ == '__main__':
32     t1 = threading.Thread(target = fun1,args = ())
33     t2 = threading.Thread(target = fun2,args = ())
34     t1.start()
35     t2.start()
36     t1.join()
37     t2.join()
fun1 申请了 l1......
fun2 申请了 l2......
fun1 等待l2......
fun2 等待l1......
out1

 

十二.锁的等待时间设置

   案例1:

 1 import time
 2 import threading
 3 
 4 lock_1 = threading.Lock()
 5 lock_2 = threading.Lock()
 6 
 7 def fun1():
 8     print('start fun1......')
 9     lock_1.acquire()
10     print('fun1 申请了 lock_1...')
11     time.sleep(2)
12     print('fun1 等待 lock_2...')
13     st = lock_2.acquire(timeout = 10)
14     if st:
15         print('fun1 申请了 lock_2...')
16         lock_1.release()
17         print('fun1 释放了 lock_1...')
18         lock_2.release()
19         print('fun1 释放了 lock_2...')
20     else:
21         print('fun1 申请 lock_2 失败')
22         lock_1.release()
23         print('fun1 释放了 lock_1...')
24     print('end fun1......')
25 
26 def fun2():
27     print('start fun2......')
28     lock_2.acquire()
29     print('fun2 申请了 lock_2...')
30     time.sleep(4)
31     print('fun2 等待 lock_1...')
32     lock_1.acquire()
33     print('fun2 申请了 lock_1...')
34     lock_2.release()
35     print('fun2 释放了 lock_2...')
36     lock_1.release()
37     print('fun2 释放了 lock_1...')
38     print('end fun2......')
39 
40 def main():
41     print('main begining......')
42     t1 = threading.Thread(target = fun1,args = ())
43     t2 = threading.Thread(target = fun2,args = ())
44     t1.start()
45     t2.start()
46     t1.join()
47     t2.join()
48     print('main end......')
49 
50 if __name__ == '__main__':
51     main()
main begining......
start fun1......
fun1 申请了 lock_1...
start fun2......
fun2 申请了 lock_2...
fun1 等待 lock_2...
fun2 等待 lock_1...
fun1 申请 lock_2 失败
fun1 释放了 lock_1...
end fun1......
fun2 申请了 lock_1...
fun2 释放了 lock_2...
fun2 释放了 lock_1...
end fun2......
main end......
out1

 

使用timeout(t),如果在t时间内没有申请到该锁,则放弃申请继续下一步

 

十三.线程处理方法

  案例1:

 1 import time
 2 import threading
 3 
 4 def fun():
 5     print('FUN START AT',time.ctime())
 6     time.sleep(3)
 7     print('FUN END AT',time.ctime())
 8 
 9 if __name__ == '__main__':
10     print('MAIN BEGIN AT',time.ctime())
11     t = threading.Timer(6,fun)
12     t.start()
13     t.join()
14     print('MAIB DONE AT',time.ctime())
MAIN BEGIN AT Sat Aug 25 20:31:14 2018
FUN START AT Sat Aug 25 20:31:20 2018
FUN END AT Sat Aug 25 20:31:23 2018
MAIB DONE AT Sat Aug 25 20:31:23 2018
out1

 timer:利用多线程,在指定时间之后启动一个功能

  案例2:

  未使用可重入锁

 1 import time
 2 import threading
 3 
 4 class My_Thread(threading.Thread):
 5     def run(self):
 6         global num
 7         time.sleep(1)
 8         if suo.acquire():
 9             num += 1
10             msg = self.name + ' set to num ' + str(num)
11             print(msg)
12             suo.acquire()
13             suo.release()
14             suo.release()
15 
16 def main():
17     for i in range(1,6):
18         print('START ',i)
19         t = My_Thread()
20         t.start()
21         print('END ',i,'\n')
22 
23 num = 0
24 suo = threading.Lock()
25 
26 if __name__ == '__main__':
27     main()  
START  1
END  1 

START  2
END  2 

START  3
END  3 

START  4
END  4 

START  5
END  5 

Thread-3 set to num 1
out2  

  案例3:

  可重入锁

 1 import time
 2 import threading
 3 
 4 class My_Thread(threading.Thread):
 5     def run(self):
 6         global num
 7         time.sleep(1)
 8         if suo.acquire():
 9             num += 1
10             msg = self.name + ' set to num ' + str(num)
11             print(msg)
12             suo.acquire()
13             suo.release()
14             suo.release()
15 
16 def main():
17     for i in range(1,6):
18         print('START ',i)
19         t = My_Thread()
20         t.start()
21         print('END ',i,'\n')
22 
23 num = 0
24 suo = threading.RLock()
25 
26 if __name__ == '__main__':
27     main()

 

START  1
END  1 

START  2
END  2 

START  3
END  3 

START  4
END  4 

START  5
END  5 

Thread-3 set to num 1
Thread-5 set to num 2
Thread-1 set to num 3
Thread-4 set to num 4
Thread-2 set to num 5
out3

 

将Lock改为RLock,即为可重入锁

使用可重入锁后,一个锁可以被一个线程多次申请 

  案例4:

  加入join()的可重入锁

 1 import time
 2 import threading
 3 
 4 class My_Thread(threading.Thread):
 5     def run(self):
 6         global num
 7         time.sleep(1)
 8         if suo.acquire():
 9             num += 1
10             msg = self.name + ' set to num ' + str(num)
11             print(msg)
12             suo.acquire()
13             suo.release()
14             suo.release()
15 
16 def main():
17     for i in range(1,6):
18         print('START ',i)
19         t = My_Thread()
20         t.start()
21         t.join()
22         print('END ',i,'\n')
23 
24 num = 0
25 suo = threading.RLock()
26 
27 if __name__ == '__main__':
28     main()
START  1
Thread-1 set to num 1
END  1 

START  2
Thread-2 set to num 2
END  2 

START  3
Thread-3 set to num 3
END  3 

START  4
Thread-4 set to num 4
END  4 

START  5
Thread-5 set to num 5
END  5 
out4

案例二三中,线程的顺序是随机的

在加入join()之后,开始排序

  案例5:

 1 import time
 2 import threading
 3 
 4 sign = threading.Semaphore(3)
 5 def fun():
 6     if sign.acquire():
 7         for i in range(5):
 8             print(threading.currentThread().getName() + 'get Semaphore')
 9         time.sleep(5)
10         sign.release()
11         print(threading.currentThread().getName() + 'release Semaphore')
12
13 def main():
14     for i in range(9):
15         t = threading.Thread(target = fun,args = ())
16         t.start()
17 
18 if __name__ == '__main__':
19     main()
Thread-1get Semaphore
Thread-1get Semaphore
Thread-1get Semaphore
Thread-1get Semaphore
Thread-1get Semaphore
Thread-2get Semaphore
Thread-2get Semaphore
Thread-2get Semaphore
Thread-2get Semaphore
Thread-2get Semaphore
Thread-3get Semaphore
Thread-3get Semaphore
Thread-3get Semaphore
Thread-3get Semaphore
Thread-3get Semaphore
Thread-2release Semaphore
Thread-3release Semaphore
Thread-4get Semaphore
Thread-4get Semaphore
Thread-4get Semaphore
Thread-4get Semaphore
Thread-4get Semaphore
Thread-5get Semaphore
Thread-5get Semaphore
Thread-1release Semaphore
Thread-5get Semaphore
Thread-6get Semaphore
Thread-6get Semaphore
Thread-6get Semaphore
Thread-6get Semaphore
Thread-6get Semaphore
Thread-5get Semaphore
Thread-5get Semaphore
Thread-4release Semaphore
Thread-7get Semaphore
Thread-7get Semaphore
Thread-7get Semaphore
Thread-7get Semaphore
Thread-7get Semaphore
Thread-5release Semaphore
Thread-8get Semaphore
Thread-8get Semaphore
Thread-8get Semaphore
Thread-8get Semaphore
Thread-8get Semaphore
Thread-6release Semaphore
Thread-9get Semaphore
Thread-9get Semaphore
Thread-9get Semaphore
Thread-9get Semaphore
Thread-9get Semaphore
Thread-9release Semaphore
Thread-7release Semaphore
Thread-8release Semaphore
out5

 Semaphore:允许一个资源最多有几个多线程同时使用

十四.线程替代方法

- subprocess
- 完全跳过线程,使用进程
- 是派生进程的主要替代方案
- python2.4后引入


- multiprocessiong
- 使用threadiing借口派生,使用子进程
- 允许为多核或者多cpu派生进程,接口跟threading非常相似
- python2.6

- concurrent.futures
- 新的异步执行模块
- 任务级别的操作
- python3.2后引入

posted @ 2018-08-25 22:33  AdriftCore  阅读(228)  评论(0编辑  收藏  举报