并发、并行、同步、异步、阻塞、非阻塞

并发

在操作系统中,是一个时间段中有几个程序都处于运行状态,而且这几个程序都是在同一个处理机器上运行,但任一个时刻点上只有一个程序在处理机上运行。总结为,系统具有处理多个任务的能力。

并行

当系统有多个CPU时,线程的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行。总结为,系统具有同时处理多个任务的能力。

直接运行函数,函数a睡眠三秒钟,函数b睡眠2秒,整个流程需要五秒钟。

import time
def a():
    print("a开始")
    time.sleep(3)
    print("a结束")
def b():
    print("b开始")
    time.sleep(2)
    print("b结束")
if __name__ == '__main__':
    t = time.time()
    print(time.strftime("%H:%M:%S",time.gmtime(t)))
    a()
    b()
    print("main")
    print(time.strftime("%H:%M:%S", time.gmtime(time.time())))
02:21:10
a开始
a结束
b开始
b结束
main
02:21:15

开启多线程,同样函数a睡眠三秒钟,函数b睡眠2秒种,整个流程只需要三秒钟。

from threading import Thread
import time
def a():
    print("a开始")
    time.sleep(3)
    print("a结束")
    print(time.strftime("%H:%M:%S", time.gmtime(time.time())))
def b():
    print("b开始")
    time.sleep(2)
    print("b结束")
    print(time.strftime("%H:%M:%S", time.gmtime(time.time())))
if __name__ == '__main__':
    t1 = Thread(target=a)
    t2 = Thread(target=b)
    print(time.strftime("%H:%M:%S", time.gmtime(time.time())))
    t1.start()
    t2.start()
    print("main")
02:19:45
a开始
b开始
main
b结束
02:19:47
a结束
02:19:48

由于GIL锁的存在,python不存在并行,所谓的并行也只是宏观上并行微观上并发,本质上是由于遇到io操作不断的cpu切换,由于cpu切换速度极快,所以看起来就像是在同时执行。在IO密集型中,多线程是可以提升任务运行速度。但是遇到计算密集型时,串行反而可能更快

锁的详细介绍

使用串行,耗时11秒

import time
def a():
    num = 0
    for i in range(10**8):
        num+=1
    print(num)
def b():
    num = 0
    for i in range(10**8):
        num += 1
    print(num)
if __name__ == '__main__':
    t = time.time()
    print(time.strftime("%H:%M:%S",time.gmtime(t)))
    a()
    b()
    print("main")
    print(time.strftime("%H:%M:%S", time.gmtime(time.time())))
02:37:41
100000000
100000000
main
02:37:52

使用多线程,耗时12秒

import time
from threading import Thread
def a():
    num = 0
    for i in range(10**8):
        num+=1
    print(num)
    print(time.strftime("%H:%M:%S", time.gmtime(time.time())))
def b():
    num = 0
    for i in range(10**8):
        num += 1
    print(num)
    print(time.strftime("%H:%M:%S", time.gmtime(time.time())))
if __name__ == '__main__':
    t1 = Thread(target=a)
    t2 = Thread(target=a)
    print(time.strftime("%H:%M:%S", time.gmtime(time.time())))
    t1.start()
    t2.start()
    print("main")

02:39:37
main
100000000
02:39:49
100000000
02:39:49

同步

当进程执行IO的时候,需要得到结果后才能继续执行

from concurrent.futures import ProcessPoolExecutor
import time
import os
def task(i):
    print(f"{os.getpid()}开始")
    time.sleep(1.5)
    print(f"{os.getpid()}结束")
    return i
if __name__ == '__main__':
    pr = ProcessPoolExecutor()
    for i in range(3):
        obj = pr.submit(task,i)
        print(obj.result())
    pr.shutdown(wait=True)
    print("=======")
    # shutdown主线程等待子线程结束后再执行
2380开始
2380结束
0
3240开始
3240结束
1
7976开始
7976结束
2
=======

异步

当进程执行IO的时候,去执行其他任务,一直等到IO结束,再回来处理。

6796开始
6224开始
8712开始
6796结束
6224结束
8712结束
0
1
2

异步调用+回调函数

回调函数:按顺序接受每个任务的结果,进行下一步处理。

注意事项

  • 进程池+回调: 回调函数由主进程去执行.
  • 线程池+回调: 回到函数由空闲的线程去执行.
  • 异步处理的IO类型.
  • 回调处理非IO

示例:

import requests
from concurrent.futures import ThreadPoolExecutor
def task(url):
    ret = requests.get(url)
    if ret.status_code == 200:
        return ret.text
def parce(ret): # 回调函数
    print(len(ret.result()))

url_list = [
        'http://www.baidu.com',
        'http://www.JD.com',
        'http://www.JD.com',
        'http://www.JD.com',
        'http://www.taobao.com',
        'http://www.baidu.com',
        'https://www.luffycity.com/',
        'http://www.baidu.com',
        'https://www.cnblogs.com/',
        'https://www.sina.com.cn/'
    ]
if __name__ == '__main__':
    t = ThreadPoolExecutor(5)
    for i in url_list:
        obj = t.submit(task,i)
        obj.add_done_callback(parce)

阻塞

当程序遇到IO时进入阻塞状态,inputjoinsleep等都是阻塞。

非阻塞

程序运行中没有任何IO就是非阻塞

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值