并发和并行

并发

通过一种算法将 CPU 资源合理地分配给多个任务,当一个任务执行 I/O 操作时,CPU 可以转而执行其它的任务,等到 I/O 操作完成以后,或者新的任务遇到 I/O 操作时,CPU 再回到原来的任务继续执行。

b1

并行

多核 CPU 的每个核心都可以独立地执行一个任务,而且多个核心之间不会相互干扰。在不同核心上执行的多个任务,是真正地同时运行,这种状态就叫做并行。

bx1

并发+并行

每个核心并发执行两个任务,两个核心并行的话就能执行四个任务。当然也可以一个核心执行一个任务,另一个核心并发执行三个任务,这跟操作系统的分配方式,以及每个任务的工作状态有关系。

bfx1


异步跟同步

图为同步/异步

a_t

同步等待上一步执行完成后才会执行下一步。

异步系统当中的解决方案是开启一个额外的线程进行处理。

第一个线程获取第一个文件,第二个线程获取第二个文件,第二个线程并不需要等待第一个线程执行完毕再执行。当两个线程都获得到对应的结果之后,再重新同步处理合并结果的操作。

同步执行

tb

异步

yb

setTimeout(function cbFn(){
    console.log('learnInPro');
}, 1000);
 
console.log('sync things');

setTimeout就是一个异步任务,当JS引擎顺序执行到setTimeout的时候发现他是个异步任务,则会把这个任务挂起,继续执行后面的代码。直到1000ms后,回调函数cbFn才会执行,这就是异步,在执行到setTimeout的时候,JS并不会傻呵呵的等着1000ms执行cbFn回调函数,而是继续执行了后面的代码。

  • 异步不会造成阻塞

  • 异步可以启用额外的线程去执行任务。

  • 异步并不会缩短任务的时间


python异步

import asyncio

# 定义异步函数
async def print_after(delay, message):
    # 异步等待
    await asyncio.sleep(delay)
    # 打印消息
    print(message)

# 获取事件循环
loop = asyncio.get_event_loop()
# 创建任务列表
tasks = [
    loop.create_task(print_after(1, 'Hello')),
    loop.create_task(print_after(2, 'World')),
]
# 在事件循环中执行任务
loop.run_until_complete(asyncio.wait(tasks))
# 关闭事件循环
loop.close()
# 多线程实现
import threading
import time

# 定义一个函数,这个函数将在一个新的线程中运行
def print_numbers():
    for i in range(10):
        time.sleep(1)
        print(i)

# 定义另一个函数,这个函数也将在一个新的线程中运行
def print_letters():
    for letter in 'abcdefghij':
        time.sleep(1)
        print(letter)

# 创建两个线程
t1 = threading.Thread(target=print_numbers)
t2 = threading.Thread(target=print_letters)

# 启动线程
t1.start()
t2.start()

# 等待线程完成
t1.join()
t2.join()
from concurrent.futures import ThreadPoolExecutor
import time

def task(n):
    time.sleep(n)
    return n

# 创建一个线程池
with ThreadPoolExecutor(max_workers=4) as executor:
    # 提交任务到线程池
    futures = [executor.submit(task, n) for n in range(1, 5)]
    # 获取任务结果
    for future in futures:
        print(future.result())

## 2
from multiprocessing import Pool

def task(n):
    return n * n

# 创建一个进程池
with Pool(processes=4) as pool:
    # 映射任务到进程池
    results = pool.map(task, range(1, 5))
    # 输出结果
    for result in results:
        print(result)

Re:

http://c.biancheng.net/view/9486.html

https://cloud.tencent.com/developer/article/1795692

https://blog.csdn.net/qq_43533974/article/details/110058714

https://www.zhihu.com/question/33515481

https://blog.csdn.net/li123128/article/details/80650256

https://www.cnblogs.com/IT-CPC/p/10898871.html