文章目录
- 什么是线程与进程
- 什么是进程
- 什么是线程
- Python 使用线程
- 实验一
- 顺序执行
- 创建线程同时执行
- 阻塞执行
- 阻塞实现串行执行(join()方法)
- 示例二:串行与并行累加
- 顺序执行累加
- 创建2个单线程分别执行累加
- 多线程阻塞执行
- 三个小实验数据对比
- 结论:
什么是线程与进程
什么是进程
进程是操作系统运行程序的一个最基本的单位,是一个程序运行的实例,也是资源分配的基本单位,一个进程关联了操作系统的资源,包括地址空间,内存,I/O,CPU等等资源,进程与进程之间是相互独立不可互访的,保持了一定的独立性,在同级别下运行进程,进程之间的资源是相互抢夺的,操作系统会进程资源进行调度。如果需要实现进程间通信,可以通过管道,文件或者socket等等进行进程间通信。
什么是线程
线程是一堆可执行程序的上下文,一个进程至少包含一个线程,而一个进程通常有多个任务需要处理,此时可通过不同的线程执行不同的任务,线程是进程执行运算的最小单位。一个进程内的所有线程都共享这个进程的所有资源。
Python 使用线程
创建线程,需要用到创建线程的模块,简单的做个小测试,执行两个函数,写上两个任务,比较执行线程与不执行线程的耗时区别:
实验一
顺序执行
import time
import threading
def firstfunction(n):
print("firstfunction:",n)
time.sleep(1)
def secondaryfunction(m):
print("secondaryfunction:",m)
time.sleep(2)
start = time.time()
print("run in the main.....")
firstfunction(1)
secondaryfunction(2)
end = time.time()
print("use time:",end-start)
"""
run in the main.....
firstfunction: 1
secondaryfunction: 2
use time: 3.0252649784088135
Process finished with exit code 0
"""
创建线程同时执行
import time
import threading
def firstfunction(n):
print("firstfunction:",n)
time.sleep(1)
def secondaryfunction(m):
print("secondaryfunction:",m)
time.sleep(2)
start = time.time()
print("run in the main.....")
threading.Thread(target=firstfunction,args=(1,)).start()
threading.Thread(target=secondaryfunction,args=(2,)).start()
end = time.time()
print("use time:",end-start)
"""
run in the main.....
firstfunction: 1
secondaryfunction: 2
use time: 0.0
Process finished with exit code 0
"""
以上两个实验,其实是一个主进程在执行,内部包含两个线程。
阻塞执行
import time
import threading
def firstfunction(n):
print("firstfunction:",n)
time.sleep(3)
print(time.time())
def secondaryfunction(m):
print("secondaryfunction:",m)
time.sleep(5)
print(time.time())
start = time.time()
print("run in the main.....")
thread1 = threading.Thread(target=firstfunction,args=(1,))
thread2 = threading.Thread(target=secondaryfunction,args=(2,))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
end = time.time()
print("use time:",end-start)
"""
run in the main.....
firstfunction: 1
secondaryfunction: 2
1610522242.126154
1610522244.1256802
use time: 5.000953912734985
Process finished with exit code 0
"""
阻塞实现串行执行(join()方法)
import time
import threading
def firstfunction(n):
print("firstfunction:",n)
time.sleep(3)
print(time.time())
def secondaryfunction(m):
print("secondaryfunction:",m)
time.sleep(5)
print(time.time())
start = time.time()
print("run in the main.....")
thread1 = threading.Thread(target=firstfunction,args=(1,))
thread2 = threading.Thread(target=secondaryfunction,args=(2,))
thread1.start()
thread1.join()
thread2.start()
thread2.join()
end = time.time()
print("use time:",end-start)
"""
run in the main.....
firstfunction: 1
1610522484.7876196
secondaryfunction: 2
1610522489.788924
use time: 8.002496004104614
Process finished with exit code 0
"""
示例二:串行与并行累加
顺序执行累加
import time
def add(n):
start = time.time()
sum = 0
for i in range(n):
sum +=i
print(sum)
end = time.time()
print("consumer time is :",end - start)
begin = time.time()
add(100000000)
add(200000000)
end = time.time()
print("main consumer time is :",end - begin)
"""
4999999950000000
consumer time is : 7.672001361846924
19999999900000000
consumer time is : 16.13348913192749
main consumer time is : 23.805490493774414
Process finished with exit code 0
"""
耗时:23.805490493774414
函数1耗时:7.672001361846924
函数2耗时:16.13348913192749
创建2个单线程分别执行累加
import time
import threading
def add(n):
start = time.time()
sum = 0
for i in range(n):
sum +=i
print(sum)
end = time.time()
print("consumer time is :",end - start)
begin = time.time()
thread1 = threading.Thread(target=add,args=(100000000,))
thread1.start()
thread2 = threading.Thread(target=add,args=(200000000,))
thread2.start()
end = time.time()
print("main consumer time is :",end - begin)
"""
main consumer time is : 0.0358586311340332
4999999950000000
consumer time is : 14.394654512405396
19999999900000000
consumer time is : 21.326332569122314
Process finished with exit code 0
"""
主线程耗时:0.0358586311340332
线程1耗时:14.394654512405396
线程2耗时:21.326332569122314
多线程阻塞执行
import time
import threading
def add(n):
start = time.time()
sum = 0
for i in range(n):
sum +=i
print(sum)
end = time.time()
print("consumer time is :",end - start)
begin = time.time()
thread1 = threading.Thread(target=add,args=(100000000,))
thread1.start()
thread1.join()
thread2 = threading.Thread(target=add,args=(200000000,))
thread2.start()
thread2.join()
end = time.time()
print("main consumer time is :",end - begin)
"""
4999999950000000
consumer time is : 7.0818071365356445
19999999900000000
consumer time is : 15.460984468460083
main consumer time is : 22.542791604995728
Process finished with exit code 0
"""
主线程耗时:22.542791604995728
线程1耗时:7.0818071365356445
线程2耗时:15.460984468460083
三个小实验数据对比
实验 | 顺序执行 | 多线程并发执行 | 多线程阻塞执行 |
主线程 | 23.805490493774414 | 0.0358586311340332 | 22.542791604995728 |
线程1 | 7.672001361846924 | 14.394654512405396 | 7.0818071365356445 |
线程2 | 16.13348913192749 | 21.326332569122314 | 15.460984468460083 |
结论:
- 顺序执行与多线程阻塞执行耗时一样,多纯种阻塞就是顺序执行
- 多线程并发执行这个程序比顺序执行的速度还慢,且时间超过了顺序执行的时间。
对于这种一直累加是需要大量的CPU来进行计算的,所以线程并发并不适合多线程,多线程是需要线程间切换来使用CPU的计算时间的,而这种频繁的切换并不适合CPU密集型的业务,所以在此小实验中,大量计算是CPU密集型,所以串行比并行效率更高。所以在Python中,如果是I/O密码型的应用,可以使用多线程,如果是CPU密集型的,请用其它语言