Python---并发编程
2017-02-08 10:19 ZN23&24 阅读(104) 评论(0) 收藏 举报进程是最小的资源单位,线程是最小的执行单位
一、进程
进程:就是一个程序在一个数据集上的一次动态执行过程。
进程由三部分组成:
1、程序:我们编写的程序用来描述进程要完成哪些功能以及如何完成
2、数据集:数据集则是程序在执行过程中所需要使用的资源
3、进程控制块:进程控制块用来记录进程的外部特征,描述进程的执行变化过程,系统可以利用它来控制和管理进程,它是系统感
知进程存在的唯一标志。
二、线程
Threading用于提供线程相关的操作。线程是应用程序中工作的最小单元,它被包含在进程之中,是进程中的实际运作单位。一
条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

1、实现线程并发
示例1:
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author: nulige
4
5 import threading #线程
6 import time
7
8 def Hi(num): #有一个参数
9 print("hello %s" %num)
10 time.sleep(3)
11
12 if __name__ == '__main__':
13
14 t1=threading.Thread(target=Hi,args=(10,)) #创建了一个线程对象t1,10做为一个参数,传给num
15 t1.start()
16
17 t2=threading.Thread(target=Hi,args=(9,)) #创建了一个线程对象t2,9做为一个参数,传给num
18 t2.start()
19
20 print("ending.........") #主线程输出ending
执行结果:
1 hello 10 #子线程 2 hello 9 #子线程 3 ending......... #主线程 4 #上面三个同时出来,再停顿三秒才结束 5 Process finished with exit code 0 #停顿3秒才结束
示例2:
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author: nulige
4
5 import threading
6 import time
7
8 def music():
9 print("begin to listen %s"%time.ctime())
10 time.sleep(3)
11 print("stop to listen %s" %time.ctime())
12
13 def game():
14 print("begin to play game %s"%time.ctime())
15 time.sleep(5)
16 print("stop to play game %s" %time.ctime())
17
18 if __name__ == '__main__':
19
20 t1=threading.Thread(target=music)
21 t1.start()
22 t2=threading.Thread(target=game)
23 t2.start()
执行结果:
1 #总共花了5秒时间 2 3 begin to listen Sat Jan 14 12:34:43 2017 4 begin to play game Sat Jan 14 12:34:43 2017 #1、先打印2个 5 6 stop to listen Sat Jan 14 12:34:46 2017 #2、等待3秒再打印一个 7 8 stop to play game Sat Jan 14 12:34:48 2017 #3、再等待2秒,打印一个
2、使用join方法
示例1:
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author: nulige
4
5 import threading
6 import time
7
8 def music():
9 print("begin to listen %s"%time.ctime())
10 time.sleep(3)
11 print("stop to listen %s" %time.ctime())
12
13 def game():
14 print("begin to play game %s"%time.ctime())
15 time.sleep(5)
16 print("stop to play game %s" %time.ctime())
17
18 if __name__ == '__main__':
19
20 t1=threading.Thread(target=music)
21 t2=threading.Thread(target=game)
22
23 t1.start() #运行实例的方法
24 t2.start()
25
26 t1.join() #子线程对象调用join()方法
27 t2.join()
28
29 print("ending") #在主线程中
执行结果:
begin to listen Sat Jan 14 12:58:34 2017 begin to play game Sat Jan 14 12:58:34 2017 #先打印2个 stop to listen Sat Jan 14 12:58:37 2017 #等待3秒,再打印一个 stop to play game Sat Jan 14 12:58:39 2017 #等待2秒,再打印两个 ending
示例2:
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author: nulige
4
5 import threading
6 import time
7
8 def music():
9 print("begin to listen %s"%time.ctime())
10 time.sleep(3)
11 print("stop to listen %s" %time.ctime())
12
13 def game():
14 print("begin to play game %s"%time.ctime())
15 time.sleep(5)
16 print("stop to play game %s" %time.ctime())
17
18 if __name__ == '__main__':
19
20 t1=threading.Thread(target=music)
21 t2=threading.Thread(target=game)
22
23 t1.start() #运行实例的方法
24 t2.start()
25
26 t1.join() #t1线程不结束,谁都不往下走
27
28 print("ending")
执行结果:
1 begin to listen Sat Jan 14 13:06:07 2017 2 begin to play game Sat Jan 14 13:06:07 2017 #先打印这两行 3 4 stop to listen Sat Jan 14 13:06:10 2017 #再等待3秒打印这两行 5 ending 6 7 stop to play game Sat Jan 14 13:06:12 2017 #再等待2秒打印这行
示例3:
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author: nulige
4
5 import threading
6 import time
7
8 def music():
9 print("begin to listen %s"%time.ctime())
10 time.sleep(3)
11 print("stop to listen %s" %time.ctime())
12
13 def game():
14 print("begin to play game %s"%time.ctime())
15 time.sleep(5)
16 print("stop to play game %s" %time.ctime())
17
18 if __name__ == '__main__':
19
20 t1=threading.Thread(target=music)
21 t2=threading.Thread(target=game)
22
23 t1.start() #运行实例的方法
24 t2.start()
25
26 t2.join()
27
28 print("ending") #在主线程中
执行结果:
1 begin to listen Sat Jan 14 13:12:34 2017 #先打印这两行 2 begin to play game Sat Jan 14 13:12:34 2017 3 4 stop to listen Sat Jan 14 13:12:37 2017 #等待3秒,打印这一行 5 6 stop to play game Sat Jan 14 13:12:39 2017 #等待2秒,打印这两行 7 ending
示例4:并没有实现并发(失去多线程的意义)
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author: nulige
4
5 import threading
6 import time
7
8 def music():
9 print("begin to listen %s"%time.ctime())
10 time.sleep(3)
11 print("stop to listen %s" %time.ctime())
12
13 def game():
14 print("begin to play game %s"%time.ctime())
15 time.sleep(5)
16 print("stop to play game %s" %time.ctime())
17
18 if __name__ == '__main__':
19
20 t1=threading.Thread(target=music)
21 t2=threading.Thread(target=game)
22
23 t1.start()
24
25 t1.join()
26 t2.start()
27
28 t2.join()
29
30 print("ending") #在主线程中
执行结果:
1 begin to listen Sat Jan 14 13:26:18 2017 #先打印条1行 2 3 stop to listen Sat Jan 14 13:26:21 2017 #等待3秒再打印2行 4 begin to play game Sat Jan 14 13:26:21 2017 5 6 stop to play game Sat Jan 14 13:26:26 2017 #等待5秒打印2行 7 ending
三、线程的两种调用方式
threading 模块建立在 thread 模块之上。thread 模块以低级、原始的方式来处理和控制线程,而 threading 模块通过对 thread
进行二次封装,提供了更方便的 api 来处理线程。
1、直接调用(推荐写法)
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author: nulige
4
5 import threading
6 import time
7
8
9 def sayhi(num): # 定义每个线程要运行的函数
10
11 print("running on number:%s" % num)
12
13 time.sleep(3)
14
15
16 if __name__ == '__main__':
17 t1 = threading.Thread(target=sayhi, args=(1,)) # 生成一个线程实例
18 t2 = threading.Thread(target=sayhi, args=(2,)) # 生成另一个线程实例
19
20 t1.start() # 启动线程
21 t2.start() # 启动另一个线程
22
23 print(t1.getName()) # 获取线程名
24 print(t2.getName())
执行结果:
1 running on number:1 2 running on number:2 3 Thread-1 4 Thread-2
2、继承式调用(有些编程人员会用这种写法,也要能看懂。不推荐这种写法)
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author: nulige
4
5 import threading
6 import time
7
8 #自己定制一个MyThread的类
9 class MyThread(threading.Thread):
10 def __init__(self, num):
11 threading.Thread.__init__(self)
12 self.num = num
13
14 def run(self): # 定义每个线程要运行的函数
15
16 print("running on number:%s" % self.num)
17
18 time.sleep(3)
19
20
21 if __name__ == '__main__':
22 t1 = MyThread(1) #继承这个类,把1这个参数,传给num ,t1就是个线程对象
23 t2 = MyThread(2)
24 t1.start()
25 t2.start()
26
27 print("ending......")
执行结果:
1 running on number:1 2 running on number:2 3 ending......
四、 threading.thread的实例方法
1、join&Daemon方法
示例1:没有用Daemon方法示例
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author: nulige
4
5 import threading
6 from time import ctime,sleep
7 import time
8
9 def ListenMusic(name):
10
11 print ("Begin listening to %s. %s" %(name,ctime()))
12 sleep(3)
13 print("end listening %s"%ctime())
14
15 def RecordBlog(title):
16
17 print ("Begin recording the %s! %s" %(title,ctime()))
18 sleep(5)
19 print('end recording %s'%ctime())
20
21 #创建一个列表,把t1和t2加到列表中去
22 threads = []
23 t1 = threading.Thread(target=ListenMusic,args=('水手',))
24 t2 = threading.Thread(target=RecordBlog,args=('python线程',))
25 threads.append(t1)
26 threads.append(t2)
27
28 if __name__ == '__main__':
29
30 for t in threads:
31 t.start()
32
33 print ("all over %s" %ctime())
执行结果:
1 Begin listening to 水手. Sat Jan 14 13:44:10 2017 2 Begin recording the python线程! Sat Jan 14 13:44:10 2017 3 all over Sat Jan 14 13:44:10 2017 #先打印三个出来; 主线程结束了 4 5 end listening Sat Jan 14 13:44:13 2017 #等待3秒,打印这1个; 子线程还没有结束,会继续往下运行 6 7 end recording Sat Jan 14 13:44:15 2017 #再等待2秒,打印这1个
示例2: 用Daemon方法示例(设置t为守护线程,就是子线程,跟着主线程一起退出)
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author: nulige
4
5 import threading
6 from time import ctime,sleep
7 import time
8
9 def ListenMusic(name):
10
11 print ("Begin listening to %s. %s" %(name,ctime()))
12 sleep(3)
13 print("end listening %s"%ctime())
14
15 def RecordBlog(title):
16
17 print ("Begin recording the %s! %s" %(title,ctime()))
18 sleep(5)
19 print('end recording %s'%ctime())
20
21 #创建一个列表,把t1和t2加到列表中去
22 threads = []
23 t1 = threading.Thread(target=ListenMusic,args=('水手',))
24 t2 = threading.Thread(target=RecordBlog,args=('python线程',))
25 threads.append(t1)
26 threads.append(t2)
27
28 if __name__ == '__main__':
29
30 for t in threads:
31 t.setDaemon(True) #设置t为守护线程; 注意:一定在start()之前设置,否则会报错
32
33 t.start()
34
35 print ("all over %s" %ctime())
执行结果:
1 Begin listening to 水手. Sat Jan 14 13:51:30 2017 #三个同时打印出来 2 Begin recording the python线程! Sat Jan 14 13:51:30 2017 3 all over Sat Jan 14 13:51:30 2017
示例3:设置t1为守护线程,没有意义,达不到效果,因为t2还会继续执行
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author: nulige
4
5 import threading
6 from time import ctime,sleep
7 import time
8
9 def ListenMusic(name):
10
11 print ("Begin listening to %s. %s" %(name,ctime()))
12 sleep(3)
13 print("end listening %s"%ctime())
14
15 def RecordBlog(title):
16
17 print ("Begin recording the %s! %s" %(title,ctime()))
18 sleep(5)
19 print('end recording %s'%ctime())
20
21 #创建一个列表,把t1和t2加到列表中去
22 threads = []
23 t1 = threading.Thread(target=ListenMusic,args=('水手',))
24 t2 = threading.Thread(target=RecordBlog,args=('python线程',))
25 threads.append(t1)
26 threads.append(t2)
27
28 if __name__ == '__main__':
29
30 t1.setDaemon(True) #设置t1为守护线程; 注意:一定在start之前设置,否则会报错
31 for t in threads:
32
33 t.start()
34
35 print ("all over %s" %ctime())
执行结果:
1 Begin listening to 水手. Sat Jan 14 14:02:07 2017 2 Begin recording the python线程! Sat Jan 14 14:02:07 2017 3 all over Sat Jan 14 14:02:07 2017 #设置t1为守护线程,所以会先把这三条先打印出来 4 5 end listening Sat Jan 14 14:02:10 2017 #再等待3秒打印t2, 6 7 end recording Sat Jan 14 14:02:12 2017 #再等待3秒打印这条出来
示例4:设置t2为守护线程,子线程才会跟着主线程一起退出
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author: nulige
4
5 import threading
6 from time import ctime,sleep
7 import time
8
9 def ListenMusic(name):
10
11 print ("Begin listening to %s. %s" %(name,ctime()))
12 sleep(3)
13 print("end listening %s"%ctime())
14
15 def RecordBlog(title):
16
17 print ("Begin recording the %s! %s" %(title,ctime()))
18 sleep(5)
19 print('end recording %s'%ctime())
20
21 #创建一个列表,把t1和t2加到列表中去
22 threads = []
23 t1 = threading.Thread(target=ListenMusic,args=('水手',))
24 t2 = threading.Thread(target=RecordBlog,args=('python线程',))
25 threads.append(t1)
26 threads.append(t2)
27
28 if __name__ == '__main__':
29
30 t2.setDaemon(True) # 设置t2为守护线程; 注意:一定在start之前设置,否则会报错
31 for t in threads:
32
33 t.start()
34
35 print ("all over %s" %ctime())
执行结果:
1 Begin listening to 水手. Sat Jan 14 14:17:09 2017 2 Begin recording the python线程! Sat Jan 14 14:17:09 2017 3 all over Sat Jan 14 14:17:09 2017 #先打印这三条 4 5 end listening Sat Jan 14 14:17:12 2017 #等待3秒,再打印这条;t1结束后,主线程也结束了。
2、一道面试题
1 #执行结果是什么? 2 3 i = 0 4 for i in range(10): 5 i += 1 6 print(i) 7 8 执行结果: 9 10
3、其它方法

示例:getName()方法 (一般没什么用)
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author: nulige
4
5 import threading
6 from time import ctime,sleep
7 import time
8
9 def ListenMusic(name):
10
11 print ("Begin listening to %s. %s" %(name,ctime()))
12 sleep(3)
13 print("end listening %s"%ctime())
14
15 def RecordBlog(title):
16
17 print ("Begin recording the %s! %s" %(title,ctime()))
18 sleep(5)
19 print('end recording %s'%ctime())
20
21 #创建一个列表,把t1和t2加到列表中去
22 threads = []
23 t1 = threading.Thread(target=ListenMusic,args=('水手',))
24 t2 = threading.Thread(target=RecordBlog,args=('python线程',))
25 threads.append(t1)
26 threads.append(t2)
27
28 if __name__ == '__main__':
29
30 t2.setDaemon(True) # 设置t为守护进程; 注意:一定在start之前设置,否则会报错
31 for t in threads:
32 t.start()
33 print(t.getName()) #返回线程名称:Thread-1
34
35 print ("all over %s" %ctime())
执行结果:
1 Begin listening to 水手. Sat Jan 14 14:36:44 2017 2 Thread-1 #返回线程名称 3 Begin recording the python线程! Sat Jan 14 14:36:44 2017 4 Thread-2 #返回默认的线程名称 5 all over Sat Jan 14 14:36:44 2017 6 end listening Sat Jan 14 14:36:47 2017

示例:threading.activeCount(),返回正在运行的线程数量
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author: nulige
4
5 import threading
6 from time import ctime,sleep
7 import time
8
9 def ListenMusic(name):
10
11 print ("Begin listening to %s. %s" %(name,ctime()))
12 sleep(3)
13 print("end listening %s"%ctime())
14
15 def RecordBlog(title):
16
17 print ("Begin recording the %s! %s" %(title,ctime()))
18 sleep(5)
19 print('end recording %s'%ctime())
20
21 #创建一个列表,把t1和t2加到列表中去
22 threads = []
23 t1 = threading.Thread(target=ListenMusic,args=('水手',))
24 t2 = threading.Thread(target=RecordBlog,args=('python线程',))
25 threads.append(t1)
26 threads.append(t2)
27
28 if __name__ == '__main__':
29
30 t2.setDaemon(True) #设置t为守护进程; 注意:一定在start之前设置,否则会报错
31 for t in threads:
32 t.start()
33
34 print("count:", threading.active_count()) #判断有多少个线程的数量
35
36 while threading.active_count()==1: #等于1就相当于只有一个主线程,没有子线程
37
38 print ("all over %s" %ctime())
执行结果:
1 Begin listening to 水手. Sat Jan 14 14:49:00 2017 2 count: 2 3 Begin recording the python线程! Sat Jan 14 14:49:00 2017 4 count: 3 #得到的线程数量 5 end listening Sat Jan 14 14:49:03 2017

浙公网安备 33010602011771号