一、什么叫多任务
多任务就是操作系统可以同时运行多个任务。比如你一边在用浏览器上网,一边在用慕课网官网学习,还一边在听音乐,这就是多任务,至少同时有3个任务正在运行。还有很多任务悄悄地在后台同时运行着,只是桌面上没有显示而已。
二、什么是进程
对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个word就启动了一个word进程,打开两个记事本就启动了两个记事本进程。大家可以在电脑上查看操作系统打开的进程,具体方法,以win8操作系统为例:在Win8传统桌面的任务栏上点击鼠标右键,选择任务管理器,即可快速打开Win8任务管理器如下:
打开之后,可以查看目前电脑都开启哪些应用进程和后台进程,以及每个进程分别所占用的计算机资源CPU、内存、磁盘等。
三、怎样的任务算一个进程当一个任务被开启后,操作系统会分配它所需的系统资源,包括内存,I/O和CPU等,如果系统资源
不够,则会出现系统崩溃,这样的任务可被称为进程。
四、在python中如何创建进程
使用的模块: multiprocessing 创建的方法: multiprocessing. Process(…)
五、什么是线程
线程(Thread)是操作系统最小的执行单元,进程至少由一个线程组成。如何调度进程和线程,完全由操作系统决定,程序自己不能决定什么时候执行,执行多长时间。有些进程还不止同时干一件事,比如微信,它可以同时进行语音、发文字、浏览信息等事情。简单理解:在一个进程内部,要同时干多件事,就需要同时运行多个“子任务”,我们把进程内的这些“子任务”称为线程。
六、怎样的任务算一个线程
进程被运行后算是一个线程,进程是不运行的,线程才会运行,而一个进程有多个线程就涉及到进程有多少可以被cpu单独调用的模块,这个调用的模块可以通过手动创建线程来建立。
七、在python中如何创建线程
使用的模块: threading
创建的方法: threading.Thread(…)
import time
def work_a():
for i in range(10): # 循环0-9
print(i,"a") # 打印循环
time.sleep(1) # 等待1秒
def work_b():
for i in range(10):
print(i,"b")
time.sleep(1)
if __name__ == "__main__" :
start = time.time() # 开始时间
work_a()
work_b()
print("耗时:",time.time() - start) # 完成时间减去开始时间
import multiprocessing
import time
import os
def work_a():
for i in range(10): # 循环0-9
print(i,"a",os.getpid()) # 打印循环 #os.getpid()查看系统的pid进程
time.sleep(1) # 等待1秒
def work_b():
for i in range(10):
print(i,"b",os.getpid())
time.sleep(1)
if __name__ == "__main__" :
start = time.time() # 开始时间
work_a()
work_b()
print("耗时:",time.time() - start) # 完成时间减去开始时间
print("parent pid is %s" % os.getpid())
import multiprocessing
import time
import os
def work_a():
for i in range(10): # 循环0-9
print(i,"a",os.getpid()) # 打印循环 #os.getpid()查看系统的pid进程
time.sleep(1) # 等待1秒
def work_b():
for i in range(10):
print(i,"b",os.getpid())
time.sleep(1)
if __name__ == "__main__" :
start = time.time() # 开始时间
a_p = multiprocessing.Process(target=work_a)# 创建多进程
a_p.start()
work_b()
print("耗时:",time.time() - start) # 完成时间减去开始时间
print("parent pid is %s" % os.getpid())
import multiprocessing
import time
import os
def work_a():
for i in range(10): # 循环0-9
print(i,"a",os.getpid()) # 打印循环 #os.getpid()查看系统的pid进程
time.sleep(1) # 等待1秒
def work_b():
for i in range(10):
print(i,"b",os.getpid())
time.sleep(1)
if __name__ == "__main__" :
start = time.time() # 主进程
a_p = multiprocessing.Process(target=work_a)# 子进程1
a_p.start() #子进程1执行
b_p = multiprocessing.Process(target=work_b) # 子进程2
b_p.start() # 子进程2执行
print("耗时:",time.time() - start) # 主进程
print("parent pid is %s" % os.getpid()) # 主进程
import multiprocessing
import time
import os
def work_a():
for i in range(10): # 循环0-9
print(i,"a",os.getpid()) # 打印循环 #os.getpid()查看系统的pid进程
time.sleep(1) # 等待1秒
def work_b():
for i in range(10):
print(i,"b",os.getpid())
time.sleep(1)
if __name__ == "__main__" :
start = time.time() # 主进程
a_p = multiprocessing.Process(target=work_a)# 子进程1
# a_p.start() #子进程1执行
b_p = multiprocessing.Process(target=work_b) # 子进程2
# b_p.start() # 子进程2执行
for p in (a_p,b_p): # 所有子进程执行
p.start()
for p in (a_p,b_p): ## 执行完子进程后 在执行下面print的主进程
p.join() # 阻塞
print("耗时:",time.time() - start) # 主进程
print("parent pid is %s" % os.getpid()) # 主进程
– 子进程1有阻塞 子进程2无阻塞 就会出现 先执行 子进程1 然后主进程 最后子进程2
import multiprocessing
import time
import os
def work_a():
for i in range(10): # 循环0-9
print(i,"a",os.getpid()) # 打印循环 #os.getpid()查看系统的pid进程
time.sleep(1) # 等待1秒
def work_b():
for i in range(10):
print(i,"b",os.getpid())
time.sleep(1)
if __name__ == "__main__" :
start = time.time() # 主进程
a_p = multiprocessing.Process(target=work_a)# 子进程1
a_p.start() #子进程1执行
a_p.join() # 子进程阻塞
b_p = multiprocessing.Process(target=work_b) # 子进程2
b_p.start() # 子进程2执行
# for p in (a_p,b_p): # 所有子进程执行
# p.start()
# for p in (a_p,b_p):
# p.join() # 阻塞
print("耗时:",time.time() - start) # 主进程
print("parent pid is %s" % os.getpid()) # 主进程
# -*- coding: utf-8 -*-
import os
import time
import multiprocessing
def work(count):
print(count,os.getpid()) # 打印进程号
time.sleep(5)
if __name__ == "__main__":
pool = multiprocessing.Pool(5) # 进程池限制5个
for i in range(20):
pool.apply_async(func=work,args=(i,))
time.sleep(20)
# -*- coding: utf-8 -*-
import os
import time
import multiprocessing
def work(count):
print(count,os.getpid()) # 打印进程号
time.sleep(5)
if __name__ == "__main__":
pool = multiprocessing.Pool(5) # 进程池限制5个
for i in range(20):
pool.apply_async(func=work,args=(i,))
pool.close()#关闭进程池,不再接受新的进程
pool.join()#主进程阻塞等待子进程的退出
# -*- coding: utf-8 -*-
import os
import time
import multiprocessing
def work(count):
print(count,os.getpid()) # 打印进程号
time.sleep(5)
return "result is %s,pid is %s"%(count,os.getpid())
if __name__ == "__main__":
pool = multiprocessing.Pool(5) # 进程池限制5个
results = []
for i in range(20):
result = pool.apply_async(func=work,args=(i,))
results.append(result)
for res in results:
print(res.get())
# -*- coding: utf-8 -*-
import os
import time
import multiprocessing
def work(count,lock):
lock.acquire()# 上锁
print(count,os.getpid()) # 打印进程号
time.sleep(5)
lock.release() # 开锁
if __name__ == "__main__":
pool = multiprocessing.Pool(5) # 进程池限制5个
manager = multiprocessing.Manager() # 进程锁 同一时间只对一个进程生效
lock = manager.Lock()
for i in range(20):
pool.apply_async(func=work,args=(i,lock))
pool.close()#关闭进程池,不再接受新的进程
pool.join()#主进程阻塞等待子进程的退出
一、当多个线程运行时,可能会出现的问题及解决方案
通过线程执行的函数无法获取返回值——线程间如何通信:通过队列多个线程同时修改文件可能造成数据错错乱——线程间如何避免资源抢占:创建线程锁
线程数量太多可能会造成资源不足,甚至死机等情况——如何避免创建线程数量过多:创建线程池
二、通过对列通信来解决
三、创建线程锁
在线程代码中需要加上锁的地方写加锁代码,要释放锁的地方写解锁代码即可
使用模块: threading
如何加锁: threading.Lock().acquire()
如何解锁: threading.Lock().release()
四、创建线程池
首先写出创建线程池的方法,之后往线程池中放入线程即可
使用的模块: concurrent.futures
import random
import time
import threading # 多线程模块
lists = ["python","django","tornado",
"flask","bs5","requests"]
new_lists = []
def work():
if len(lists) == 0 :
return
data = random.choice(lists) #从非空序列中随机选取一个数据并返回
lists.remove(data)# remove() 函数可以删除列表中的指定元素
new_data = "%s_new"% data # 重命名
new_lists.append(new_data) # 追加到新列表
time.sleep(1) # 等待1秒
if __name__=="__main__":
start = time.time() # 开始时间
for i in range(len(lists)): # 按照列表的长度循环运行work函数
work()
print("old list:",lists) # 打印lists列表内容
print("new list:",new_lists) # 打印new list列表内容
print("time is %s"%(time.time()-start)) # 耗时
import random
import time
import threading # 多线程模块
lists = ["python","django","tornado",
"flask","bs5","requests"]
new_lists = []
def work():
if len(lists) == 0 :
return
data = random.choice(lists) #从非空序列中随机选取一个数据并返回
lists.remove(data)# remove() 函数可以删除列表中的指定元素
new_data = "%s_new"% data # 重命名
new_lists.append(new_data) # 追加到新列表
time.sleep(1) # 等待1秒
if __name__=="__main__":
start = time.time() # 开始时间
t_list = []
for i in range(len(lists)): # 按照列表的长度循环运行work函数
t = threading.Thread(target=work) # 实例化一个线程
t_list.append(t)
t.start() # 启动线程
for t in t_list:
t.join()# 阻塞 运行完子程序后在运行下面的打印
print("old list:",lists) # 打印lists列表内容
print("new list:",new_lists) # 打印new list列表内容
print("time is %s"%(time.time()-start)) # 耗时
import time
import threading
import concurrent
from concurrent.futures import ThreadPoolExecutor
lock = threading.Lock() # 实例化一个线程锁
def work(i):
# lock.acquire()
print(i)
time.sleep(1)
# lock.release()
if __name__=="__main__":
t = ThreadPoolExecutor(2) # 线程池2个线程
for i in range(20):
t.submit(work,(i,))
import time
import threading
import concurrent
from concurrent.futures import ThreadPoolExecutor
lock = threading.Lock() # 实例化一个线程锁
def work(i):
lock.acquire()
print(i)
time.sleep(1)
lock.release()
if __name__=="__main__":
t = ThreadPoolExecutor(2) # 线程池2个线程
for i in range(20):
t.submit(work,(i,))
异步相对同步而言,同步意味着有序,异步意味着无序,正因为异步的无序,使得各个程序间的协调成为一大难题,异步编程就是解决这一难题的编程,它是以进程、线程、协程、函数/方法作为执行任务程序的基本单位,结合回调、事件循环、信号量等机制,以提高程序整体执行效率和并发能力的编程方式
Python中如何实现异步
方法一:
如何定义一个异步,使用关键字: async
在一个异步程序里,如何调用另一个异步,使用关键字: await
如何调用一个异步函数,使用模块: asyncio
同步执行实例
import time
def a():
for i in range(10):
print(i,"我是A")
time.sleep(1)# 等待时间
return "a function"
def b():
for i in range(10):
print(i,"我是B")
time.sleep(1)
return "b function"
if __name__=="__main__":
start = time.time()
a()
b()
print("耗时%s"%(time.time()-start))
import time
import asyncio
async def a():
for i in range(10):
print(i,"我是A")
await asyncio.sleep(1) # time.sleep是cpu级别的阻塞我们需要更改asyncio.sleep
return "a function"
async def b():
for i in range(10):
print(i,"我是B")
await asyncio.sleep(1)
return "b function"
async def main():
result = await asyncio.gather(
a(),
b()
)
print(result)
if __name__=="__main__":
start = time.time()
asyncio.run(main())
print("耗时%s"%(time.time()-start))
import time
import gevent
def gevent_a():
for i in range(10):
print(i,"我是A")
gevent.sleep(1) # 阻塞
return "我是gevent a result"
def gevent_b():
for i in range(10):
print(i,"我是B")
gevent.sleep(1)
return "我是gevent b result"
if __name__=="__main__":
start = time.time()
g_a = gevent.spawn(gevent_a)
g_b = gevent.spawn(gevent_b)
gevent_list = [g_a,g_b]
result = gevent.joinall(gevent_list)
print(result)
print("耗时%s"%(time.time()-start))