1.现代操作系统:
OS X,UNIX,Linux,Windows 等都是支持“多任务”的操作系统
单核CPU:通过操作系统轮流让各个任务交替执行,从CPU的视角看,每个任务都是交替执行的,由于CPU的执行速度非常快,我们感觉就像所有任务都在同时执行一样。
多核CPU:由于任务数量远远多于CPU的核心数量,操作系统会自动把很多任务轮流调度到每个核心上执行。
**并发:**看上去一起执行,任务数多于CPU核心数
**并行:**真正一起执行,任务数小于等于CPU核心数
实现多任务的方式:1.多线程模式 2.多进程模式 3.协程模式 4.多进程+多线程
一个正在执行的任务就是一个进程,比如打开一个浏览器就是启动一个浏览器进程(程序执行和资源分配的基本单位,数据段,代码段和堆栈段)
关于进程线程介绍比较详细的网站:https://zhuanlan.zhihu.com/p/46368084
2.启动进程实现多任务:
from multiprocessing import Process
def func(str):
while True:
print("hi hi %s"%(str))
time.sleep(1.2)
if __name__=="__main__":
print("主进程启动")
#创建子进程
#target说明进程执行的任务
p = Process(target=func,args=(" ",)
#启动进程
p.start()
while True:
print("hello hellio")
time.sleep(1)
#os.getpid()获取当前进程的ID号
#os.getppid()获取当前进程的父进程的id号
3.父子进程的先后顺序
from multiprocessing import Process
def func():
print("子进程启动")
time.sleep(3)
print("子进程结束")
if __name__=="__main__":
print("父进程启动")
p=Process(target=func)
p.strat()
print("父进程结束")
程序执行结果:父进程启动
父进程结束
子进程启动
子进程结束
#父进程的结束不能影响子进程,让父进程等子进程结束再执行父进程:
p.join()
4.全局变量在多个进程中不能共享
num = 100
def func():
print("子进程开始")
global num
num+=1
print(num)
print("子进程结束")
if __name__="__main__":
print("父进程开始")
p=Process(target=func)
p.start()
p.join()
print(num)
print("父进程结束")
#在创建子进程时对全局变量做了备份,父进程与子进程中的num是两个完全不同的变量
5.启动大量子进程
def func(name):
print("子进程%d启动--%s"%(name,os.getpid() ))
start = time.time()
time.sleep(random.choice([1,2,3]))
end = time.time()
print("子进程%d结束--%s--耗时%.2f")%(name,os.getpid(),end-start)
if __name__ =="__main__":
print("父进程启动")
#创建多个进程,进程池
#pool默认大小是cpu核心数
p=Pool(2)
for i in rang(3):
#创建进程,放入进程池
p.apply_async(run,args=(i,))
#调用join前必须先调用close,调用close后不能再继续添加新的进程
p.close()
p.join()
print("父进程结束")
6.实现文件拷贝
import os
from multiprocessing import Pool
#复制文件的方法
def copyFile(rPath,wPath):
fr = open(rpath,"rb")
fw = open(wpath,"wb")
context = fr.read()
fw.write(context)
fr.close()
fw.close()
path=" "
topath=" "
#读取路径下的所有文件
fileList = os.listdir(path)
#启动for循环处理每一个文件
start = time.time()
for fileName in fileList:
copyFile(os.path.join(path,fileName),os.path.join(topath.fileName))
end = time.time()
print("总耗时%0.2f"%(end-start))
用进程方式实现文件拷贝
if __name__=="__main__":
# 读取path下的所有文件
fileList = os.listdir(path)
start = time.time()
pp=Pool(2)
for fileName in fileList:
pp.apply_async(copyFile, args=(os.path.join(path,filename),os.path.join
(toPath,filename) ))
pp.close()
pp.join()
end = time.time()
#分装进程对象
from multiprocessing import Process
class SunckProcess(Process):
def __init__(self, name):
Process.__init__(self)
self.name = name
def run(self):
print("")
time.sleep(3)
print("")
from sunckProces import SunckProcess
if __name__ == "__main__":
p = SunckProcess("test")
#自动调用p进程对象的run方法
p.start()
p.join()
print("父进程结束")
7.进程间的通信
write read
A B C
from multiprocessing import Process, Queue
def write(q):
print("启动写子进程%d"%(os.getpid()))
for chr in ["A","B","C","D"]:
q.put(chr)
time.sleep(1)
print("结束写子进程%d"%(os.getpid()))
def read():
print("启动读子进程%d"%(os.getpid()))
while True:
value = q.get(True)
print("value="+value)
print("结束读子进程%d"%(os.getpid()))
if __name__="__main__":
#父进程创建队列,并传递给子进程
q=Queue()
pw = Process(target=write, args=(q,))
pr = Process(target=read, args=(q,))
pw.start()
pr.start()
pw.join()
#强制结束
pr.terminate()
print("父进程结束")
8.线程
#一个进程内部 同时干多件事,需要同时运行多个“子任务”,这些子任务叫做线程
线程管理主要通过threading模块。
threading模块提供的类:Thread, Lock, Rlock, Condition, Semaphore, Event, Timer, local。
常用方法:
threading.currentThread() 返回当前的线程变量
threading.enumerate() 返回一个包含正在运行的线程的list
threading.activeCount():返回正在运行的线程数量
模块常量:
threading.TIMEOUT_MAX设置threading全局超时时间。
Thread类属性: name:线程名 ident:线程的标识符 daemon:布尔值,表示这个线程是否是守护线程
Thread类方法:init(group=None, target=None, name=None, args=(),kwargs={}, verbose=None, daemon=None)
实例化一个线程对象,需要一个可调用的target对象,以及参数args或者kwargs。还可以传递name和group参数。
start():开始执行该线程
run():定义线程的方法
join(timeout=None) 直至启动的线程终止之前一直挂起;
启动线程
import threading,time
def run():
print("子线程(%s)开始"%(threading.current_thread().name))
#实现线程的功能
print("打印")
time.sleep(2)
print("子线程(%s)开始"%(threading.current_thread().name))
if __name__=="__main__":
#任何进程默认会启动一个线程,称为主线程,主线程可以启动新的子线程
print("主线程(%s)启动"%(threading.current_thread().name))
#创建子线程
t = threading.Thread(target=run, name="runThread")
t.start()
#等待线程结束
t.join()
print("主线程(%s)结束"%(threading.current_thread().name))
多线程和多进程最大的不同在于,多进程中 同一个变量各自有一份拷贝存在每个进程中互不影响。 多线程中,所有变量由线程共享,任何一个变量可以被任意一个线程修改。
num=10
def run(n):
global num
for i in range(10000):
num = num+n
num = num-n
if __name__=="__main__":
t1 = threading.Thread(target=run,args=(6,))
t2 = threading.Thread(target=run,args=(9,))
t1.start()
t2.start()
t1.join()
t2.join()
print("num=",num)