同步处理,也被称为是阻塞式处理,是指程序执行到某个位置,会一直等待该命令执行完毕,然后继续执行后续逻辑。
异步处理,是指一段程序由多个线程或进程同时执行,从而提高软件性能。
线程是计算机调度的基本单位,一个进程至少有一个线程。线程是轻量级的,线程的启动、调度对操作系统来说所耗资源较少,所以大多数软件都涉及了多个线程来并行执行程序,从而提高运行速度。线程的调度不是认为控制的,而是由操作系统决定的,创建多线程只是为一个软件争取更多被调度到的机会。
# -*- coding: UTF-8 -*-
import threading
import time
def get_data_from_db():
print("当前线程名称:{0}".format(threading.current_thread().name))
for i in range(5):
time.sleep(1) # 表示“睡眠”一秒
print("{0} 线程执行完毕!".format(threading.current_thread().name))
if __name__ == "__main__":# 用于对当前模块进行测试。如果是直接执行当前模块,则判断为True;如果该模块被导入其他模块中,则判断为False.
print("{0} 线程开始运行".format(threading.current_thread().name))
thread = threading.Thread(target=get_data_from_db, name="新线程")#threading.Thread()创建了一个线程实例
thread.start()# 表示启动创建的新线程
thread.join()# 是一个阻塞式方法,表示在当前位置等待新线程结束,之后在在主线程继续执行
print("{0} 线程执行完毕!".format(threading.current_thread().name))
# -*- coding: UTF-8 -*-
import time, threading
global_score = 100
lock = threading.Lock()
def update_score(score):
for i in range(200000):
lock.acquire() # 获取“锁”
global global_score
global_score = global_score + score
global_score = global_score - score
lock.release() # 释放“锁”
threads = []
for i in range(10):
thread = threading.Thread(target=update_score, args=(i * 10,)) # 创建10个线程对象,每个线程负责执行各自的回调函数update_score
threads.append(thread)
for i in threads:
i.start() # 将线程全部启动,但10个线程不会同时执行,每个线程获取到锁,在对全局变量操作结束后释放锁,中间不会切换线程,这个过程是原子性的。
for i in threads:
i.join()
print("global_score值:", global_score)
文件是静态的,进程是动态的。不同进程是独立运行的,拥有各自的内存空间、数据资源、文件资源等。一个进程可以创建另一个进程,称为当前进程的子进程。
# -*- coding: UTF-8 -*-
import time
from multiprocessing import Process
import os
def new_process(para):
time.sleep(10)
print("子进程ID:{0}".format(os.getpid()))
print("主进程传递来的参数:{0}".format(para))
if __name__ == "__main__":
print("父进程ID是:{0}".format(os.getpid()))
process = Process(target=new_process, args=("主进程参数",))
process.start()# 启动进程
process.join()# 等待子进程执行完毕,再执行主进程
print("主进程执行完毕!")
当主进程需要同时管理多个进程的时候,可以使用进程池。如下所示:
# -*- coding: UTF-8 -*-
from multiprocessing import Pool
import time
def proc(num):
print("当前进程编号:{0} 开始执行".format(num))
time.sleep(5)
print("当前进程编号:{0} 执行结束".format(num))
if __name__ == "__main__":
pool = Pool(3) # 创建一个进程池对象,并且进程池中同时运行的进程个数为3个
print("创建5个进程")
for i in range(5):
process_num = "{0}".format(i)
pool.apply_async(proc, args=(process_num,)) # 用于创建进程
pool.close()# 表示不能再有新的进程加入pool
pool.join()
print("主进程执行完毕!")
# -*- coding: UTF-8 -*-
from multiprocessing import Process, Queue
import os, time
def set_data(q, tmp_list):
for item in tmp_list:
print("当前{0}进程将值 {1} 插入队列".format(os.getpid(), item))
q.put(item)
time.sleep(2)
def get_data(q, count):
for i in range(count):
value = q.get(True)
print("当前{0}进程获取到值为:{1}".format(os.getpid(), value))
if __name__ == "__main__":
que = Queue()
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
length = len(data)
process1 = Process(target=set_data, args=(que, data))
process2 = Process(target=get_data, args=(que, length))
process1.start()
process2.start()
process2.join()
print("主进程执行完毕!")
其执行结果如图:
也可以参考之间的博文:Python使用socket实现两进程之间的传输数据
Python提供了async关键字创建的异步函数,就是协程。异步函数的返回值并不是该函数的执行结果,而是一个协程对象,协程对象调用send方法才会触发异步函数的执行。如下所示:
# -*- coding: UTF-8 -*-
import time
async def get_data_from_db(counter):
data = []
print("参数counter:", counter)
for i in range(counter):
time.sleep(1)
data.append(i)
return data
coroutine_obj = get_data_from_db(5)
print("异步函数返回值:",coroutine_obj)
try:
coroutine_obj.send(None)
except Exception as e:
print(e)
参考:《python数据分析与大数据处理》