找回密码
 立即注册
搜索

[开发] 同步与异步的区别(一看则懂)

[复制链接]
智慧谋略 发表于 2024-3-12 12:31:28 | 显示全部楼层 |阅读模式
概况:同步是阻塞模式,异步是非阻塞模式
同步的理解: 同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去;
同步就相当于是 当客户端发送请求给服务端,在等待服务端响应的请求时,客户端不做其他的事情。当服务端做完了才返回到客户端。这样的话客户端需要一直等待。用户使用起来会有不友好

异步的理解: 异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。
异步就相当于当客户端发送给服务端请求时,在等待服务端响应的时候,客户端可以做其他的事情,这样节约了时间,提高了效率。
  存在就有其道理 异步虽然好 但是有些问题是要用同步用来解决,比如有些东西我们需要的是拿到返回的数据在进行操作的。这些是异步所无法解决的。

ps:加深你的理解小例子:
  • 比方说一个人边吃饭,边看手机,边说话,就是异步处理的方式。
  • 同步处理就不一样了,说话后在吃饭,吃完饭后在看手机,必须等待上一件事完了,才执行后面的事情。
  • 而在前端开发中常见的异步一般常见的包括:setTimeout,setInterval,ajax
  • setTimeout是定时延时运行函数,只执行一次
  • setInterval也是定时延时函数,但是这个函数本身可以一直执行,不会停止,除非把它清除。
  • ajax是前端常用的和后台进行异步交互数据的请求方式,其实它本身也包括同步和异步,同步的就是由代码从上到下顺序执行,而异步的ajax是我们发送请求到服务器之后,只需要在监听服务器的响应即可,不用等到请求结束在执行其他的代码,这就是异步ajax




 楼主| 智慧谋略 发表于 2024-3-12 13:05:53 | 显示全部楼层
同步 vs 异步:在现代软件架构中的关键区别1.背景介绍在现代软件架构中,同步和异步是两个非常重要的概念,它们在多线程、多进程、分布式系统等方面都有着重要的作用。同步和异步在处理并发问题时有着不同的表现,它们在系统性能、可靠性、安全性等方面也有着不同的影响。因此,理解同步和异步的区别和应用场景,对于设计和实现高性能、高可靠、高安全性的软件架构至关重要。
本文将从以下几个方面进行阐述:
  • 背景介绍
  • 核心概念与联系
  • 核心算法原理和具体操作步骤以及数学模型公式详细讲解
  • 具体代码实例和详细解释说明
  • 未来发展趋势与挑战
  • 附录常见问题与解答
1. 背景介绍1.1 并发与并行在现代软件架构中,并发和并行是两个与同步和异步密切相关的概念。
并发(Concurrency)是指多个任务在同一时间内运行的情况,而并行(Parallelism)是指多个任务同时运行,分别占用硬件资源,如CPU核心、内存等。
并发可以通过多线程、多进程、消息队列等方式实现,而并行通常需要多核、多处理器等硬件支持。
1.2 同步与异步的出现同步和异步的出现是为了解决并发和并行在实际应用中遇到的问题。
在早期的软件系统中,由于硬件资源有限,通常只能运行一个任务。随着硬件技术的发展,多任务调度技术逐渐成熟,使得多个任务可以在同一时间内运行。但是,这种多任务调度方式存在一些问题,如任务之间的互斥、同步、资源竞争等。为了解决这些问题,同步和异步这两种并发控制方式诞生了。
同步和异步的出现使得软件系统能够更高效地运行多个任务,提高了系统性能和可靠性。
2. 核心概念与联系2.1 同步同步(Synchronization)是指在并发环境中,多个任务之间的相互协同和互动。同步可以通过锁、信号量、条件变量等同步原语实现。
同步的主要特点是:
  • 同步任务之间存在先后关系,前一个任务只能在后一个任务完成后才能继续执行。
  • 同步任务可以相互阻塞,一个任务执行过程中可以等待另一个任务的完成。
2.2 异步异步(Asynchronous)是指在并发环境中,多个任务之间不存在严格的先后关系,任务之间可以独立执行,不会互相阻塞。异步可以通过回调函数、Promise、生成器等异步原语实现。
异步的主要特点是:
  • 异步任务之间不存在先后关系,每个任务可以在其他任务执行过程中开始或结束。
  • 异步任务不会相互阻塞,一个任务执行过程中不会等待另一个任务的完成。
2.3 同步与异步的联系同步和异步是两种不同的并发控制方式,它们之间存在一定的联系:
  • 同步可以看作是异步的特例,在同步中,任务之间存在严格的先后关系和互相阻塞。
  • 异步可以通过将同步任务转换为异步任务来实现,例如使用回调函数将同步I/O操作转换为异步I/O操作。
  • 同步和异步在实际应用中可以相互组合,例如使用线程池和事件循环等技术来实现混合并发控制。
2.4 同步与异步的区别同步和异步在并发控制方面有以下区别:
  • 同步任务在其他任务执行的过程中不能开始,只有等待执行的任务完成后才能开始执行。异步任务可以在其他任务执行的过程中开始,不需要等待执行的任务完成。
  • 同步任务可以相互阻塞,一个任务执行过程中可以等待另一个任务的完成。异步任务不会相互阻塞,一个任务执行过程中不会等待另一个任务的完成。
  • 同步任务在执行过程中可能会导致死锁,异步任务通常不会导致死锁。
  • 同步任务在多线程、多进程等并行环境中可能会导致资源竞争,异步任务通常不会导致资源竞争。
3. 核心算法原理和具体操作步骤以及数学模型公式详细讲解
3.1 同步原语
3.1.1 锁

锁(Lock)是一种同步原语,用于实现同步任务之间的互斥访问。锁可以分为互斥锁(Mutex)、读写锁(ReadWriteLock)、计数锁(Counting Semaphore)等类型。
锁的主要操作步骤:
  • 尝试获取锁。如果锁已经被其他线程占用,则阻塞当前线程,等待锁释放。
  • 如果获取锁成功,则执行临界区代码。
  • 释放锁。
数学模型公式:
L={ acquire_lock()  if lock_available()
      wait()               if lock_occupied()
      release_lock()  if hold_lock()

3.1.2 信号量
信号量(Semaphore)是一种同步原语,用于控制多个线程对共享资源的访问。信号量可以分为计数信号量(Counting Semaphore)和二值信号量(Binary Semaphore)。
信号量的主要操作步骤:
  • 获取信号量。如果信号量值大于0,则减少信号量值,并执行临界区代码。
  • 释放信号量。增加信号量值。
数学模型公式:
S={  acquire_semaphore()     release_semaphore()
​      if semaphore_available()  if hold_semaphore()​
3.1.3 条件变量条件变量(Condition Variable)是一种同步原语,用于实现线程之间的同步和通信。条件变量可以分为广播(Broadcast)和信号(Signal)两种类型。
条件变量的主要操作步骤:
  • 等待条件变量。将当前线程加入条件变量的等待队列,并释放锁。
  • 唤醒条件变量。从条件变量的等待队列中唤醒一个线程,并将其加入到锁的获得队列中。
数学模型公式:
CV=⎨ wait()             if condition_not_met()
          broadcast()   if condition_met()               
         signal()​         if condition_met()​
3.2 异步原语3.2.1 回调函数回调函数(Callback)是一种异步原语,用于处理异步任务的结果。回调函数可以在异步任务完成后自动调用,或者在特定事件发生时调用。
回调函数的主要操作步骤:
  • 注册回调函数。将回调函数注册到异步任务中,以便在异步任务完成后调用。
  • 异步任务执行。异步任务在后台执行,不阻塞主线程。
  • 调用回调函数。在异步任务完成后,自动调用注册的回调函数。
数学模型公式:
CB={  register_callback()     if callback_not_registered()
         execute_async_task()    if callback_registered
        invoke_callback()if task_completed()
3.2.2 PromisePromise是一种异步原语,用于处理异步任务的结果,并提供一种链式调用机制。Promise可以表示一个异步操作的结果,当异步操作完成时,Promise可以解析为一个值,或者被拒绝为一个错误。
Promise的主要操作步骤:
  • 创建Promise对象。创建一个新的Promise对象,用于表示异步任务的结果。
  • 注册回调函数。将成功和失败的回调函数注册到Promise对象中。
  • 异步任务执行。异步任务在后台执行,不阻塞主线程。
  • 解析或拒绝Promise。在异步任务完成后,根据任务的结果,解析或拒绝Promise对象。
  • 调用回调函数。当Promise对象解析或拒绝后,调用注册的回调函数。
数学模型公式:
P={  create_promise()       if promise_not_created()
       register_callbacks()    if promise_created()
      execute_async_task()  if callbacks_registered()
      resolve_promise()      if task_completed()
      reject_promise()        if error_occurred()

3.2.3 生成器
生成器(Generator)是一种异步原语,用于实现异步任务的迭代和流程控制。生成器可以通过yield关键字实现暂停和恢复执行,以及将值传递给调用者。
生成器的主要操作步骤:
  • 创建生成器函数。创建一个生成器函数,使用yield关键字实现暂停和恢复执行。
  • 调用生成器函数。调用生成器函数,创建生成器对象。
  • 迭代生成器对象。使用for循环或其他迭代方法,迭代生成器对象,并执行生成器函数中的代码。
  • 传递值。在迭代生成器对象时,可以传递值给生成器函数的yield表达式。
数学模型公式:
G={ create_generator()       if generator_not_created()
       yield()                           if generator_created()
       execute_async_task()   if yield_value()
      resume_generator()     if value_received()
4. 具体代码实例和详细解释说明4.1 同步代码实例
  1. import threading
  2. import time

  3. def task():
  4.     print("任务开始执行")
  5.     time.sleep(2)
  6.     print("任务执行完成")

  7. lock = threading.Lock()

  8. def main():
  9.     with lock:
  10.         print("开始执行同步任务")
  11.         task()
  12.         print("同步任务执行完成")

  13. if __name__ == "__main__":
  14.     main()
复制代码

在这个代码实例中,我们使用了threading模块中的Lock类来实现同步任务的互斥访问。在main函数中,我们首先获取锁,然后执行任务。由于任务使用了sleep函数导致延迟,因此主线程在等待任务完成之前会被阻塞。
4.2 异步代码实例
  1. import asyncio

  2. async def task():
  3.     print("任务开始执行")
  4.     await asyncio.sleep(2)
  5.     print("任务执行完成")

  6. async def main():
  7.     print("开始执行异步任务")
  8.     await task()
  9.     print("异步任务执行完成")

  10. if __name__ == "__main__":
  11.     asyncio.run(main())
复制代码

在这个代码实例中,我们使用了asyncio模块来实现异步任务的执行。在main函数中,我们使用await关键字调用任务,并在任务完成后继续执行下一步代码。由于任务使用了sleep函数导致延迟,因此主线程在等待任务完成之前不会被阻塞。
5. 未来发展趋势与挑战5.1 未来发展趋势
  • 异步编程的普及。随着异步编程的发展,越来越多的编程语言和框架支持异步编程,这将使得编写高性能、高可靠的软件架构变得更加简单和直观。
  • 事件驱动编程。事件驱动编程已经成为现代软件架构的重要组成部分,将会继续发展,以满足各种应用场景的需求。
  • 流式计算。随着大数据时代的到来,流式计算将成为软件架构的重要组成部分,用于处理实时数据和流式计算任务。
5.2 挑战
  • 异步编程的复杂性。虽然异步编程可以提高软件性能,但它也增加了编程的复杂性。开发人员需要具备相应的异步编程技能,以确保编写正确和高效的异步代码。
  • 线程和进程的管理。随着并发任务的增加,线程和进程的管理变得越来越复杂。开发人员需要具备相应的并发编程技能,以确保高效地管理线程和进程。
  • 资源竞争和死锁的避免。随着并发任务的增加,资源竞争和死锁的风险也会增加。开发人员需要具备相应的并发编程技能,以确保避免资源竞争和死锁。
6. 附录常见问题与解答6.1 同步与异步的优劣同步的优点:
  • 简单易用。同步编程相对简单,易于理解和实现。
  • 数据一致性。同步编程可以确保数据的一致性,避免数据不一致的问题。
同步的缺点:
  • 低效率。同步编程可能导致线程阻塞,降低系统性能。
  • 资源竞争。同步编程可能导致资源竞争,增加系统复杂度。
异步的优点:
  • 高效率。异步编程不会导致线程阻塞,提高系统性能。
  • 更好的资源利用。异步编程可以更好地利用系统资源,降低资源竞争。
异步的缺点:
  • 复杂度较高。异步编程相对复杂,需要更高的编程技能。
  • 数据一致性。异步编程可能导致数据不一致的问题,需要特殊处理。
6.2 同步与异步的应用场景同步的应用场景:
  • 短任务。当任务执行时间较短,不会导致线程阻塞的情况下,可以使用同步编程。
  • 高数据一致性要求。当需要确保数据的一致性的情况下,可以使用同步编程。
异步的应用场景:
  • 长任务。当任务执行时间较长,需要避免线程阻塞的情况下,可以使用异步编程。
  • 高并发场景。当需要处理大量并发请求的情况下,可以使用异步编程。
6.3 同步与异步的混合使用在实际应用中,同步和异步可以相互组合,以实现更高效的并发控制。例如,可以使用线程池和事件循环等技术来实现混合并发控制。线程池可以用于管理同步任务,事件循环可以用于管理异步任务。通过这种方式,可以充分利用系统资源,提高软件性能。




高级模式
B Color Image Link Quote Code Smilies

本版积分规则

Archiver|手机版|小黑屋|探索掌握未知、共创美好未来

GMT+8, 2026-9-17 02:30 , Processed in 0.048004 second(s), 32 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表