操作系统(10) (并发(2)------基于软件/硬件/操作系统层面解决两个进程之间的临界区问题/抢占式/非抢占式内核)

目录

1. 基于软件层面(Peterson's Solution)

Peterson's Solution 满足三个要求:

好处:

缺点

2. 基于硬件层面

        1. Disabling Interrupts (禁用中断)

概念解释:

代码框架:

        要求:

        禁用中断的好处与问题:

2. Test and Set Lock (测试并设置锁, TSL) 

        第一部分 - 概述

        第二部分 - 锁的工作机制

        Test-and-Set 锁的工作机制

c. CAS(Compare_and_Swap)硬件方法

CAS的定义

CAS的要求:

​​​​​​​​​​​​​​​​​CAS的优点:

CAS的缺点:

1. 抢占式内核(Preemptive kernels)

2. 非抢占式内核(Non-preemptive kernels)


1. 基于软件层面(Peterson's Solution)

do {
    flag[i] = true;        // i wants to enter critical section
    turn = j;              // allow j to access first

    while (flag[j] && turn == j)
        ; // busy wait

    // CRITICAL SECTION
    flag[i] = false;

    // REMAINDER SECTION
} while (true);
do {
    flag[j] = true;        // j wants to enter critical section
    turn = i;              // allow i to access first

    while (flag[i] && turn == i)
        ; // busy wait

    // CRITICAL SECTION
    flag[j] = false;

    // REMAINDER SECTION
} while (true);
  • flag[2] 数组:每个进程都有一个布尔值来表示它是否想要进入临界区。
    • flag[0] 表示 Process P0 是否想要进入临界区。
    • flag[1] 表示 Process P1 是否想要进入临界区。
  • turn 变量:决定哪个进程可以进入临界区。它可以是 0(P0的轮次)或 1(P1的轮次),只有没有轮到的进程才会等待。

假设有两个进程 ij

  • i 想要进入临界区时,它会设置 flag[i] = true,表示自己准备进入,并设置 turn = j,表示优先让 Process j 进入。
  • 如果此时 Process j 没有想要进入临界区(即 flag[j] = false),那么 Process i 会进入临界区。
  • 如果 Process j 也想进入临界区,Process i 会根据 turn 的值决定自己是忙等待还是进入临界区。

当 Process i 完成临界区任务后,它会将 flag[i] 设置为 false,释放临界区,允许 Process j 进入。

总结

  • flag:用来表示进程是否想要进入临界区。
  • turn:决定哪个进程可以优先进入。
  • 互斥机制:通过轮流方式解决临界区访问冲突,确保不会同时有多个进程进入临界区。

Peterson's Solution 满足三个要求:

  1. Mutual Exclusion(互斥)
    • 在任意时刻,只有一个进程可以进入临界区。这个互斥性是解决临界区问题的核心要求之一,防止多个进程同时修改共享资源导致数据不一致。
  2. Progress(进展)
    • 理论上,Peterson 算法保证了进展,即不会有进程无限等待。每个进程都有机会进入临界区。然而,在实际操作中,由于调度行为等因素,进程的进展可能会被延迟,或者在某些情况下一个进程可能似乎“饥饿”了(无法及时进入临界区)。
  3. Bounded Waiting(有界等待)
    • Peterson's Solution 理论上保证了有限等待的特性,这意味着每个进程都有机会在有限时间内进入临界区。但在实际应用中,有时可能会发生一个进程被系统偏爱,而另一个进程会因为饥饿问题而无法及时进入临界区。

好处:

  1. 易于理解和实现
    • Peterson 的算法在处理两个进程的临界区问题时非常简单易懂,并且实现起来也不复杂。
  2. 不需要特殊硬件
    • 与一些依赖于硬件支持的算法不同,Peterson's Solution 不需要依赖硬件级的原子操作或者禁用中断。它只使用简单的共享变量,通过软件级别的方式实现同步。

缺点

1. Limited to two processes (仅限于两个进程)

  • 扩展性差Peterson's Solution 仅支持两个进程同时操作,这意味着无法处理多个进程。这在现代操作系统中是一个严重的局限,因为多个进程常常需要同时访问共享资源。
    • "Limited to two processes" 表示 Peterson's Solution 只能处理两个进程的互斥问题,无法扩展到多个进程使用。
  • 扩展困难:虽然理论上可以通过增加更多的标志位(flag)和更复杂的条件来支持多个进程,但这会导致代码复杂度和错误率增加。
    • flag 是指布尔标志,用来表示进程是否要进入临界区 (Critical Section)。如果多个进程要共享资源,管理这些标志位和调度将变得极其复杂。

2. Busy waiting leads to inefficient use of CPU resources (忙等待导致CPU资源利用低效)

  • 忙等待问题Busy Waiting 是指进程在等待时,不断循环检查条件是否满足,这会消耗大量的 CPU 资源,而这些资源本可以用于其他任务。
    • Busy Waiting 是一种低效的资源管理方法,因为进程在循环中没有做实际有用的工作,只是在不断检查能否进入临界区。
  • 资源浪费:由于进程反复检查标志位(flag[]turn),在等待期间未做任何有用的计算,导致了 CPU 资源的浪费。
    • turn 是控制进程轮流进入临界区的变量。在忙等待过程中,CPU 的资源被用来持续检查这些变量是否允许进入临界区。

3. Performance Issues on Modern Architectures (现代架构上的性能问题)

  • Cache Coherence Problems (缓存一致性问题):在多核处理器上,每个核(core)有自己的缓存(Cache),并非所有处理器会立即看到共享变量的变化。Peterson's Solution 假设共享变量的更新能被所有核及时看到,这在现代架构中并不总是成立,可能会导致错误。
    • Cache Coherence (缓存一致性) 问题出现在当处理器各自处理局部缓存时,变量的更新未能及时同步到其他处理器上,导致不同步的访问。
  • Memory Model (内存模型问题):现代处理器会进行诸如指令重排(Instruction Reordering)和乱序执行(Out-of-Order Execution)等优化操作。这些操作会改变代码执行的顺序,破坏 Peterson's Solution 的基本假设,即变量的读写必须严格按顺序进行。
    • 在现代处理器中,指令重排有时会打乱程序执行顺序,导致变量更新的延迟,进而影响 Peterson's Solution 的同步准确性。

4. No fairness or priority mechanism, which may lead to starvation (缺乏公平性或优先级机制,可能导致饥饿问题)

  • 缺乏公平性:Peterson's Solution 确保了进程互斥,但它没有保证进程之间的公平竞争。某些进程可能会被系统优先调度,而其他进程长时间得不到执行机会,导致 Starvation (饥饿) 问题。
    • Starvation (饥饿) 是指某个进程由于调度机制的原因,长时间无法获得资源使用权限,从而无法执行。
  • 无优先级机制:Peterson's Solution 不能支持不同重要性进程之间的优先级调度。如果一个进程比另一个进程更重要,该算法无法确保重要的进程优先进入临界区。
    • Priority (优先级) 控制指的是,系统应当能够识别进程的重要性,并基于此分配资源。在 Peterson's Solution 中,这种优先级机制不存在。

5. Lack of Deadlock Prevention (缺乏死锁预防)

  • 无法预防死锁:Peterson's Solution 确保两个进程不会同时进入临界区(Critical Section),但它不能预防外部资源竞争导致的 Deadlock (死锁)。如果两个进程在等待外部资源(例如文件锁或数据库连接)时,可能会相互阻塞,导致死锁。
    • Deadlock (死锁) 是指两个或多个进程由于互相等待对方释放资源,导致所有进程都无法继续执行。

2. 基于硬件层面

        1. Disabling Interrupts (禁用中断)

  1. 概念解释:

    • 当进程进入临界区 (Critical Section) 时,它会禁用中断 (Disable Interrupts)。这样确保在进程执行临界区代码时,不会发生上下文切换 (Context Switch),时钟中断 (Clock Interrupt),或其他系统中断。这保证了进程的独占执行,直到它退出临界区。
      • Interrupts (中断) 是操作系统用来暂停当前执行进程并处理紧急任务(如硬件请求)的一种机制。在禁用中断期间,这些请求将无法被处理,确保当前进程独占 CPU 资源。
  2. 代码框架:

  • 逻辑说明:禁用中断 -> 执行临界区代码 -> 重新启用中断 -> 处理剩余代码。
  • 这种方法主要确保了临界区中的代码可以独占执行,不会被打断。

要求:

  1. 单处理器系统中的应用:
    • 单处理器系统 (Single-Processor System) 中,禁用中断部分满足了临界区问题的要求,但有一定的局限性。
  2. 优点:
    • Mutual Exclusion (互斥):禁用中断可以保证互斥性,只有当前进程可以进入临界区,因为没有其他进程有机会获得 CPU 的控制权。
  3. 缺点:
    • Progress (进展):整个系统的性能可能受损,尤其是其他进程(例如,依赖中断的 I/O 绑定进程)在等待中断被启用时无法执行。这会影响系统的整体进程调度。
    • Bounded Waiting (有界等待):禁用中断不保证有界等待。如果一个进程长时间禁用中断,其他等待进入临界区或依赖中断的进程可能会被无限期延迟。

禁用中断的好处与问题:

  1. Benefits (好处)
    • Exclusive access (独占访问):一旦禁用中断,CPU 不会切换到其他进程,允许当前进程在没有中断的情况下执行临界区操作。
      • 无中断:确保了进程的独占性,不会受到其他进程或事件的干扰。
    • Simplicity (简单性):禁用中断的方法简单有效,尤其在单处理器系统中,容易实现互斥。
  2. Drawbacks (问题)
    • Affects system responsiveness (影响系统响应能力):禁用中断会阻止系统及时处理重要任务,例如 I/O 或外部事件,这可能导致系统反应迟缓。
      • 响应问题:进程长时间占用 CPU,会让系统无法及时处理来自外部的硬件请求或用户输入。
    • Not scalable (无法扩展到多处理器系统):此方法不适合多处理器系统。在多处理器系统中,禁用一个处理器的中断并不能防止其他处理器上的进程进入临界区或访问共享资源。
      • 多核问题:只禁用一个 CPU 的中断无法阻止其他 CPU 的进程进行操作,这在多处理器环境下导致禁用中断方法的无效性。

2. Test and Set Lock (测试并设置锁, TSL) 

第一部分 - 概述

  1. Lock Variable (锁变量)
    • 这是一个共享的锁变量(通常是一个比特位或内存位置),用于指示临界区 (Critical Section) 是否空闲(值为 0 表示解锁 "unlocked")或被占用(值为 1 表示锁定 "locked")。
    • 锁的作用:防止多个进程/线程同时进入临界区。
  2. Test-and-Set Instruction (测试并设置指令)
    • 硬件支持的原子操作 (Atomic Operation),称为 test-and-set,确保操作不可分割,避免其他进程/线程在操作过程中干扰。具体步骤如下:
      • 检查锁的当前值。
      • 如果锁是空闲的(值为 0),则将其设置为锁定(值为 1),同时返回旧值。
      • 如果操作是原子性的,其他进程/线程不能在操作未完成前看到中间状态或干扰操作。

示例代码 (图示中)

第二部分 - 锁的工作机制

  1. 流程:
    • 如果进程成功将锁设置为 1,则可以进入临界区。其他进程/线程将被阻止,因为锁现在是锁定状态。
    • 当进程完成临界区的代码后,它会将锁重置为 0,允许其他进程/线程进入。
  2. 锁的初始值是 0 (false)
    • 在锁未被占用时,值为 0,表示解锁状态,进程可以进入临界区。
    • 当锁定时,锁的值变为 1,表示当前临界区正在被占用,其他进程必须等待。
  3. 代码示例 (图示中的 P1 P2)
    • 两个进程 P1 和 P2 通过检查锁变量,进入临界区并执行代码。只有当锁值为 0 时,进程才能进入临界区,设置锁为 1 并阻止其他进程进入。

 

Test-and-Set 锁的工作机制

  1. 锁的初始状态
    • 当程序启动时,锁的初始值通常设置为 0,表示未锁定状态(解锁)。这意味着临界区是空闲的,任何进程/线程都可以尝试进入。
  2. 进程如何使用锁
    • 假设有两个进程 P1P2,它们都想进入临界区执行某些操作。
    • 它们首先使用 test_and_set() 函数检查锁的状态,并根据返回值决定是否可以进入临界区。
  3. test_and_set() 函数
    • test_and_set() 函数是一个原子操作,意味着它在执行过程中不可被其他进程/线程打断。
    • test_and_set() 做两件事:
      1. 检查锁的当前值:它会检查当前锁变量的值,如果锁的值是 0,表示解锁状态,进程可以进入临界区。
      2. 设置锁:如果锁是空闲的(值为 0),它会将锁的值设置为 1,表示锁定状态。这个过程是原子的,意味着只有一个进程能成功将锁设置为 1。
  4. 如何保证互斥 (Mutual Exclusion)
    • 只有一个进程可以成功进入临界区
      • 当第一个进程(例如 P1)调用 test_and_set() 时,它会发现锁的值是 0,表示未被锁定。于是,P1 会将锁设置为 1,并成功进入临界区执行任务。
      • 如果另一个进程(P2)在 P1 已经锁定的情况下也调用 test_and_set(),P2 会发现锁的值已经是 1,这意味着临界区被锁定,因此 P2 不能进入,它会进入等待状态。
      • P2 会持续检查锁变量,直到锁的值再次变为 0(即解锁状态)。
  5. 释放锁
    • P1 完成它的临界区任务后,它会将锁的值重置为 0,这就表示解锁,允许其他等待的进程(如 P2)进入临界区。
  6. 总结锁的状态变化
    • 初始状态:锁的值是 0,表示临界区空闲。
    • 第一个进程进入:第一个调用 test_and_set() 的进程会将锁值设置为 1,锁定临界区。
    • 其他进程等待:在锁定期间,其他进程调用 test_and_set() 时会发现锁已经是 1,因此它们必须等待。
    • 进程完成任务后释放锁:进程完成任务后,会将锁重置为 0,表示解锁,其他进程可以再次尝试进入临界区。

1. Test-and-Set锁的要求

  • 互斥(Mutual Exclusion
    • Test-and-Set锁保证同一时刻只有一个进程可以进入临界区,从而满足互斥要求。
  • 进展(Progress
    • 理论上,进展是可以保证的,但在实际中,忙等待(busy-waiting)可能导致低效和延迟,特别是在系统负载高的情况下。尽管没有进程被阻塞,但进程可能由于调度或系统负载问题而变得缓慢。
  • 有界等待(Bounded Waiting
    • Test-and-Set锁并不保证有界等待。忙等待会让进程无限期地在等待锁定过程中徘徊,导致某些进程可能被其他进程长时间阻塞,从而引发饥饿问题(starvation)。

2. Test-and-Set锁的优点

  • 简单高效
    • Test-and-Set锁很容易实现,并且确保了互斥,使其在需要快速解决问题的场合中非常实用。
  • 适用于小临界区
    • 如果临界区很短,争用锁的情况不严重,那么Test-and-Set锁会显得非常高效。这种情况下,忙等待所消耗的CPU资源相对较少,系统开销较小。

3. Test-and-Set锁的缺点

  • 忙等待问题(Spinlock Overhead
    • 使用Test-and-Set锁时,进程在等待锁时会持续忙等待,占用CPU资源。特别是当临界区较长或存在大量竞争线程时,忙等待会导致CPU资源浪费,降低系统效率。
  • 饥饿风险(Starvation Risk
    • Test-and-Set锁不保证所有进程都有机会访问临界区。尤其是在高度竞争的环境中,一些进程可能永远无法获得锁,导致饥饿
  • 扩展性问题(Scalability Issues
    • 随着并发进程或线程数量的增加,锁的争用变得更为严重,忙等待的开销也会增加。因此,在高并发环境下,这种锁的效率下降。
  • 死锁风险(Deadlock Potential
    • 如果Test-and-Set锁使用不当,可能会导致死锁。例如,如果某个进程在持有锁的情况下再次尝试获取锁,它将阻塞自身,从而导致死锁。

总结:

  • 互斥可以通过Test-and-Set锁来保证,但这种方法存在明显的缺点,比如忙等待导致资源浪费、饥饿问题和扩展性差。在高并发或临界区较长的情况下,这种锁可能不再适用。
  • 需要注意的是,死锁风险必须通过合理的锁管理来避免,这也是Test-and-Set锁需要特别小心的地方。

c. CASCompare_and_Swap硬件方法

  1. CAS的定义:

  • CAS 是一种硬件支持的 原子操作(atomic operation。它能够确保在多处理器系统中执行的操作不会被打断。
  • 工作原理
    • 比较:它首先会检查存储在某个内存地址上的值是否与期望值相符。
    • 交换:如果当前值与期望值匹配,它将用新的值替换旧值。
    • 返回:最后,CAS 操作会返回是否执行了替换操作,返回旧值。
  1. 代码实现
  • 代码展示了 compare_and_swap() 的实现。CAS 操作将原子地比较并替换锁的值。
  • lock 表示锁所在的内存位置。
  • expected 是期望的当前值,new_value 是需要设置的新值。

       2. CAS的要求

  • 互斥:由于 CAS 是原子操作,所以它能够确保 互斥(Mutual Exclusion,即一次只有一个进程能进入临界区。
  • 进度:CAS可以确保进度,但是如果没有公平性机制(如退避策略基于队列的CAS策略),可能会出现**忙等待(busy waiting)**问题,导致部分进程一直占用临界区,影响其他进程的进度。
  • 有界等待(Bounded Waiting:CAS 并不能保证有界等待,这意味着一些进程可能会被长时间延迟,因为某些进程反复成功获取锁。
    • ​​​​​​​​​​​​​​​​​​​​​​​​CAS的优点

  • 支持多处理器:CAS 在现代多处理器系统中得到了很好的支持,非常适合大规模、高性能的应用程序。
  •  
    • CAS的缺点

  • 忙等待(Spinlock:如同Test and Set一样,CAS 操作在无法获取锁时会忙等待,导致 CPU 资源浪费,特别是当锁被长时间持有时。
  • 没有公平性:CAS 操作不能保证公平性,可能导致某些进程长期无法进入临界区,进而导致**饥饿(Starvation)**问题。

1. 抢占式内核(Preemptive kernels

  • 在抢占式内核中,进程在内核模式下运行时,可以被中断,另一个进程可能会被调度。这意味着:
    • 多个进程可以同时在内核中运行,但这会导致潜在的竞争条件(race conditions。竞争条件是指多个进程并发地访问共享资源时,由于访问顺序的不确定性,可能导致数据不一致或错误。
  • 需要同步机制来避免这些竞争条件,常用的同步方法包括:
    • 锁(locks
    • 互斥锁(mutexes
    • 原子操作(atomic operations
  • 例子:Windows 和 Linux 都使用抢占式内核。这些系统需要额外的同步机制来确保内核中的数据一致性。

2. 非抢占式内核(Non-preemptive kernels

  • 在非抢占式内核中,进程一旦进入内核模式,它将继续运行,直到其完成阻塞主动让出CPU为止。在此期间,其他进程不会中断它的执行。
    • 因此,在这种内核模式下,没有竞争条件,因为同一时刻只会有一个进程在内核中活动。
  • 由于没有多个进程并发执行,因此不需要复杂的同步机制,这简化了系统设计。
  • 例子:老旧或简单的操作系统,如早期的MS-DOS或一些嵌入式系统(embedded systems,通常使用非抢占式内核。

总结:

  • 抢占式内核允许多个进程同时在内核模式下运行,但需要复杂的同步机制来处理共享数据。
  • 非抢占式内核确保只有一个进程在内核中执行,因此不需要同步机制,但可能导致效率低下,因为无法在进程阻塞时进行上下文切换。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/908413.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于 JAVASSM 框架沙县小吃点餐系统

基于 JAVASSM 框架(即 Java Spring Spring MVC MyBatis)开发一个沙县小吃点餐系统。 步骤一:需求分析 明确系统需要实现的功能,比如: 用户注册和登录浏览菜单添加菜品到购物车下单并支付订单管理后台管理&#…

零基础Java第十三期:继承与多态(一)

目录 一、继承 1.1. 继承的目的 1.2. 继承的概念 1.3. 继承的语法 1.4. 父类的访问 1.5. 继承中的重载与重写 1.6. 子类的构造方法 1.7. 再谈初始化 一、继承 1.1. 继承的目的 我们来定义一个Dog和Cat的类: public class Dog {public int age;public Strin…

论文翻译 | Evaluating the Robustness of Discrete Prompts

摘要 离散提示已被用于调整预训练语言模型,以适应不同的NLP任务。特别是,从一小组训练实例中生成离散提示的自动方法已经报告了优越的性能。然而,仔细观察习得的提示会发现,它们包含嘈杂和反直觉的词汇结构,而这些在手…

SQL,力扣题目1549,每件商品的最新订单【窗口函数】

一、力扣链接 LeetCode_1549 二、题目描述 表: Customers ------------------------ | Column Name | Type | ------------------------ | customer_id | int | | name | varchar | ------------------------ customer_id 是该表主键. 该表包含消费者的…

mysql查表相关练习

作业要求: 单表练习: 1 . 查询出部门编号为 D2019060011 的所有员工 2 . 所有财务总监的姓名、编号和部门编号。 3 . 找出奖金高于工资的员工。 4 . 找出奖金高于工资 40% 的员工。 5 找出部门编号为 D2019090011 中所有财务总监,和…

广东网站设计提升你网站在搜索引擎中的排名

在当今网络盛行的时代,拥有一个设计优良的网站,对企业的在线发展至关重要。特别是对于广东地区的企业来说,网站设计不仅仅是美观的问题,更直接影响着搜索引擎中的排名。因此,精心策划和设计的网站,能够显著…

qt QGroupBox详解

1、概述 QGroupBox是Qt框架中的一个容器控件,主要用于组织和管理一组相关的控件(如按钮、复选框、文本框等),并为这些控件提供一个框架和标题。通过使用QGroupBox,可以创建具有逻辑分组和视觉层次结构的用户界面&…

数据库管理-第256期 Oracle DB 23.6新特性一览(20241031)

数据库管理256期 2024-10-31 数据库管理-第256期 Oracle DB 23.6新特性一览(20241031)1 AI向量搜索:新的向量距离度量2 混合向量索引3 分区:本地邻近分区向量索引4 持久邻近图向量索引5 稀疏向量6 邻居图向量索引的事务支持7 特征…

应急响应----本地环境配置,对内存马的研究分析

应急响应----本地环境配置,对内存马查杀研究分析 注:后续添加的补充内容框架型内存马 SpringController型内存马:动态注册Controller及映射路由。 SpringInterceptor型内存马:动态注册Interceptor及映射路由。 启动环境: Spring框架启动(Controller型内存马和Intercept…

JAVA 插入 JSON 对象到 PostgreSQL

博主主页:【南鸢1.0】 本文专栏:JAVA 目录 ​编辑 简介 所用: 1、 确保 PostgreSQL 数据库支持 JSON: 2、添加 PostgreSQL JDBC 驱动 3、安装和运行 PostgreSQL 4、建立数据库的连接 简介 在现代软件开发中,由于 JSON 数据…

AUTOSAR CP NVRAM Manager规范导读

一、NVRAM Manager功能概述 NVRAM Manager是AUTOSAR(AUTomotive Open System ARchitecture)框架中的一个模块,负责管理非易失性随机访问存储器(NVRAM)。它提供了一组服务和API,用于在汽车环境中存储、维护和恢复NV数据。以下是NVRAM Manager的一些关键功能: 数据存储和…

机器学习:我们能用机器学习来建立投资模型吗

机器学习模型能解决什么投资问题? 利用机器学习解决投资问题的思路,其实和在互联网领域解决推荐、广告问题的思路是一样的,只不过利用的特征完全变了。推荐、广告模型利用的是用户的年龄、性别,物品的类别、价格等特征&#xff0c…

FBX福币交易所国际油价突然大涨!美伊针锋相对

11月4日早上,国际原油大幅高开。WTI原油一度涨超2%。 消息面上,主要产油国宣布延长自愿减产措施至12月底 FBX福币凭借用户友好的界面和对透明度的承诺,迅速在加密货币市场中崭露头角,成为广大用户信赖的平台。 石油输出国组织(欧佩克)发表声明说,8个欧佩克和非欧佩克产油国决…

Flarum:简洁而强大的开源论坛软件

Flarum简介 Flarum是一款开源论坛软件,以其简洁、快速和易用性而闻名。它继承了esoTalk和FluxBB的优良传统,旨在提供一个不复杂、不臃肿的论坛体验。Flarum的核心优势在于: 快速、简单: Flarum使用PHP构建,易于部署&…

独立开发的个人品牌打造:个人IP与独立开发的结合

引言 个人品牌程序员也需要打造。在当今的创意经济中,个人IP与独立开发的结合成为了一种趋势,为个体带来了前所未有的机会和可能性。本文将探讨如何通过打造个人IP来增强独立开发的影响力,并探索这种结合为个人带来的潜在价值。 个人IP的重…

细说STM32单片机USART中断收发RTC实时时间并改善其鲁棒性的方法

目录 一、工程目的 1、 目标 2、通讯协议及应对错误指令的处理目标 二、工程设置 三、程序改进 四、下载与调试 1、合规的指令 2、 proBuffer[0]不是# 3、proBuffer[4]不是; 4、指令长度小于5 5、指令长度大于5 6、proBuffer[2]或proBuffer[3]不是数字 7、;位于p…

AI助力医疗:未来的医生会是机器人吗?

内容概要 在这一场医疗科技的新浪潮中,AI医疗正以前所未有的速度渗透到各个角落。随着技术的飞速进步,人工智能成为了推动医疗领域革新的重要力量。从精准诊断到个性化治疗,AI正在帮助医生们更快速、准确地分析患者的病情,提高了…

数据结构 ——— 向上调整建堆和向下调整建堆的区别

目录 前言 向下调整算法(默认小堆) 利用向下调整算法对数组建堆 向上调整建堆和向下调整建堆的区别​编辑 向下调整建堆的时间复杂度: 向上调整建堆的时间复杂度: 结论 前言 在上一章讲解到了利用向上调整算法对数组进行…

图数据库 2 | 大数据的演进和数据库的进阶——从数据到大数据、快数据,再到深数据

时至今日,大数据已无处不在,所有行业都在经受大数据的洗礼。但同时我们也发现,不同于传统关系型数据库的表模型,现实世界是非常丰富、高维且相互关联的。此外,我们一旦理解了大数据的演进历程以及对数据库进阶的强需求…

java版询价采购系统 招投标询价竞标投标系统 招投标公告系统源码

在数字化时代,企业需要借助先进的数字化技术来提高工程管理效率和质量。招投标管理系统作为企业内部业务项目管理的重要应用平台,涵盖了门户管理、立项管理、采购项目管理、采购公告管理、考核管理、报表管理、评审管理、企业管理、采购管理和系统管理等…