进程和线程的区别:
- 进程:是程序运行的实体,比如windows10上的任务管理器种,我们可以看到很多进程在运行
- 线程:一个进程中可以并发多个线程,每条线程执行不同的任务
- 线程适合于多IO操作
- 进程适合于CPU的操作
一、多进程(multiprocessing):
由于Python是跨平台的,自然也提供了一个跨平台的多进程支持。multiprocessing
模块就是跨平台版本的多进程模块。
(1)Process类
multiprocessing
模块提供了一个Process
类来代表一个进程对象:Process ( target , args ),target表示调用对象,args表示调用对象的位置参数元组。
实例1:创建函数并将其作为单个进程,启动这个子进程并等待其结束
from multiprocessing import Process
import os
def worker(name):
print("子进程是%s:%s" %(name, os.getpid()))
if __name__ == "__main__":
print("父进程:%s" % os.getpid())
# target表示调用对象,args表示调用对象的位置参数元祖
p = Process(target=worker, args=('p1',))
# 启动子进程
p.start()
# 等待子进程结束后继续往下执行,通常用于进程间的同步
p.join() #如果注释,则主程序不会等待子进程运行结束再往下执行,而值直接会运行下面的内容
print("子进程运行结束!")
运行结果:
父进程:18744
子进程是p1:25268
子进程运行结束!
如果注释p.join,运行结果是:
父进程:27424
子进程运行结束!
子进程是p1:8584
实例2:创建函数并将其作为多个进程,启动这些子进程并等待结束
from multiprocessing import *
import time
import os
def worker_1(t):
print("子进程1:", os.name, os.getpid())
time.sleep(t)
print("end worker_1")
def worker_2(t):
print("子进程2:", os.name, os.getpid())
time.sleep(t)
print("end worker_2")
def worker_3(t):
print("子进程3:", os.name, os.getpid())
time.sleep(t)
print("end worker_3")
if __name__ == "__main__":
p1 = Process(target=worker_1, args=(4,))
p2 = Process(target=worker_2, args=(3,))
p3 = Process(target=worker_3, args=(2,))
start = time.time()
p1.start()
p2.start()
p3.start()
p1.join()
p2.join()
p3.join()
# 总消耗时间大致为子进程消耗时间最长的时间:4s
end = time.time() - start
print("消耗的时间为:", end)
运行结果:
子进程2: nt 29740
子进程1: nt 32288
子进程3: nt 27796
end worker_3
end worker_2
end worker_1
消耗的时间为: 4.668010950088501
(2)Pool:
如果程序需要启动大量的子进程,就可以采用进程池的方式批量创建子进程。
Pool
对象调用join()
方法会等待所有子进程执行完毕,在调用join()
之前必须先调用close()
,调用close()
之后就表示不能继续添加新的Process
了。
实例1:每个进程消耗的时间为16秒,同时执行9个进程,消耗的总时间大致为8秒;
# 因为采用p = Pool()
# 创建进程池,默认一次执行的进程个数为CPU的核数,我的电脑为8,
# 所以,一次只能执行8个进程,等前8个进程某一个进程结束,在继续第9个进程,
# (注意:不是8个都结束才进行第9个进程,是8个中的任意一个结束就开始执行下个进程);
from multiprocessing import Pool
import time
import os
# 子进程
def worker(name, t):
print("child process:", name, os.getpid())
time.sleep(t)
print("end child process %s" % name)
if __name__ == "__main__":
print("parent process:", os.getpid())
start = time.time()
# 创建进程池,默认的个数为CPU的核数
p = Pool()
for i in range(9):
p.apply_async(worker, args=(i,8))
# 9个进程之后不再添加新的进程对象
p.close()
p.join()
end = time.time() - start
print("消耗时间为:", end)
运行结果:
parent process: 11420
child process: 0 18604
child process: 1 31232
child process: 2 24152
child process: 3 684
child process: 4 4236
child process: 5 24828
child process: 6 9664
child process: 7 28788
end child process 0
child process: 8 18604
end child process 1
end child process 3
end child process 2
end child process 5
end child process 4
end child process 6
end child process 7
end child process 8
消耗时间为: 16.663140773773193
二、多线程(threading
)
要实现多个任务的并发,可以由多进程完成。使用多线程类似于同时执行多个不同程序
示例1:创建函数并将其作为单个线程,启动这个线程并等待其结束;
任何进程默认就会启动一个线程,我们把该线程称为主线程,主线程又可以启动新的线程,Python的threading模块有个current_thread()函数,它永远返回当前线程的实例。
主线程实例的名字叫MainThread,子线程的名字在创建时指定,我们用childThread命名子线程。
import time
from threading import *
def worker():
print('thread %s is running' % current_thread().name)
n = 0
while n < 5:
n = n + 1
print('thread %s -->%s' % (current_thread().name, n))
time.sleep(1)
print('thread %s ended.' % current_thread().name)
if __name__=='__main__':
start = time.time()
# 当前线程
print('thread %s is running' % current_thread().name)
t = Thread(target=worker, name='ChildThread')
# 开启线程
t.start()
# 线程结束后回到主程序
t.join()
print('thread %s ended.' % current_thread().name)
end = time.time() - start
print("消耗时间为:", end)
运行结果:
thread MainThread is running
thread ChildThread is running
thread ChildThread -->1
thread ChildThread -->2
thread ChildThread -->3
thread ChildThread -->4
thread ChildThread -->5
thread ChildThread ended.
thread MainThread ended.
消耗时间为: 5.003291845321655
示例2:创建函数并将其作为多个线程,启动这些子进程并等待其结束;通过上下两个例子可以发现,最终的耗时都是5秒,所以,线程是同步执行的。
import time
from threading import *
# 线程执行的代码
def worker():
print('thread %s is running' % current_thread().name)
n = 0
while n < 5:
n = n + 1
print('thread %s--->%s'%(current_thread().name, n))
time.sleep(1)
print('thread %s ended.' % current_thread().name)
if __name__ == "__main__":
start = time.time()
# 当前线程
print('thread %s is running' % current_thread().name)
t1 = Thread(target=worker, name='childThread1')
t2 = Thread(target=worker, name='childThread2')
# 开启编程
t1.start()
t2.start()
# 线程结束后回到主程序
t1.join()
t2.join()
print('thread %s ended' % current_thread().name)
end = time.time() - start
print("消耗时间为:", end)
运行结果:
thread MainThread is running
thread childThread1 is running
thread childThread1--->1
thread childThread2 is running
thread childThread2--->1
thread childThread1--->2
thread childThread2--->2
thread childThread1--->3
thread childThread2--->3
thread childThread1--->4
thread childThread2--->4
thread childThread1--->5
thread childThread2--->5
thread childThread1 ended.
thread childThread2 ended.
thread MainThread ended
消耗时间为: 5.006869554519653
善于跌倒仍喜爱奔跑~