操作系统 --- 进程的同步和互斥问题以及进程互斥实现方法(软件、硬件实现)、同步机制遵循的四条准则

目录

一、进程同步 

二、进程互斥 

三、进程互斥的实现方法

3.1 软件实现

3.1.1 单标志法(存在的主要问题:违背“空闲让进”原则)

3.1.1.1 基本思想

3.1.1.2 单标志法的基本概念及执行流程

3.1.1.3 特点

3.1.2 双标志先检查法(违反了忙则等待原则)

 3.1.2.1 基本思想

3.1.2.2 基本概念及执行流程

3.1.2.3 特点

3.1.3 双标志后检查法

3.1.3.1 算法思想

3.1.3.2 执行流程代码 

3.1.4  Peterson算法

3.1.4.1 算法思想 

3.1.4.2 算法步骤

3.1.4.3 两个进程并发运行时会带来什么后果

3.1.4.4 Peterson算法的特点

3.2 软件实现方法总结

3.3 硬件实现

 3.3.1 中断屏蔽法

3.3.2 利用Test-and-Set指令实现互斥

3.3.3 利用Swap指令实现进程互斥


一、进程同步 

知识点回顾:进程具有异步性的特征。异步性是指,各并发执行的进程以各自独立的、不可预知的速度向前推进。
进程同步:
同步亦称直接制约关系,它是指为完成某种任务而建立的两个或多个进程,这些进程因为需要在某些位置上协调它们的工作次序而产生的制约关系。进程间的直接制约关系就是源于它们之间的相互合作。

二、进程互斥 

      进程的“并发”需要“共享”的支持。各个并发执行的进程不可避免地需要共享一些系统资源(比如内存,打印机、摄像头这样的I/O设备)。

两种资源共享

  • 互斥共享方式。系统中的某些资源,虽然可以提供给多个进程使用,但一个时间段内只允许一个进程访问该资源。
  • 同时共享方式。系统中的某些资源,允许一个时间段内由多个进程“同时”对它们进行访问。

      我们把一个时间段内只允许一个进程使用的资源称为临界资源。许多物理设备(比如摄像头、打印机)都属于临界资源。此外还有许多变量、数据、内存缓冲区等都属于临界资源。
      对临界资源的访问,必须互斥地进行。互斥,亦称间接制约关系。
进程互斥指当一个进程访问某临界资源时,另一个想要访问该临界资源的进程必须等待。当前访问临界资源的进程访问结束,释放该资源之后,另一个进程才能去访问临界资源。 

对临界区资源的互斥访问,可以在逻辑上分为如下四个部分:
 
进入区:负责检查是否可进入临界区,若可进入,则应设置正在访问临界资源的标志(可理解为“上锁”),以阻止其他进程同时进入临界区。
临界区:访问临界资源的那段代码。
退出区:负责解除正在访问临界资源的标志(可理解为“解锁”)。
剩余区:做其他处理。执行临界区操作之外的其他处理任务。

注意:
临界区是进程中访问临界资源的代码段。
进入区和退出区是负责实现互斥的代码段。
临界区也可称为“临界段” 

思考问题: 如果一个进程暂时不能进入临界区,那么该进程是否应该一直占着处理机?该进程有没有可能一直进不了临界区? 

为实现进程互斥地进入自己的临界区,可用软件方法,更多的是在系统中设置专门的同步机构来协调各进程间的运行。所有同步机制都应遵循下述四条准则:
(1) 空闲让进。临界区空闲时,可以允许一个请求进入临界区的进程立即进入临界区;
(2) 忙则等待。当已有进程进入临界区时,其他试图进入临界区的进程必须等待;这种原则的特点是在一个进程试图进入临界区时,如果发现资源正被另一个进程占用,它不会立即让出 CPU,而是不断检查条件,直到资源可用为止。这种行为会导致 CPU 的时间片被浪费在空循环中,这就是“忙等待”。
(3) 有限等待。对请求访问的进程,应保证能在有限时间内进入临界区(保证不会饥饿);
(4) 让权等待。 当进程不能进入临界区时,应立即释放处理机,防止进程忙等待。【进程的忙等待(busy waiting)是指一个进程在等待某个条件满足时,持续地检查该条件,而不让出CPU时间。这个过程通常会导致浪费CPU资源,因为进程在等待期间不断地占用CPU,而不是进行其他有用的工作】 

三、进程互斥的实现方法

如果没有进程互斥?会带来什么后果?
假设进程A、进程B在系统中并发地运行,如下:

先调度A上处理机运行
当A在使用打印机的过程中,分配给它的时间片用完了,接下来操作系统调度B让它上处理机运行
进程B也在使用打印机
结局:A、B的打印内容混在一起了。

      这种情况是我们不愿意看到的,如果引入互斥,那么在进程A还没有执行完打印任务之前进程B是不可能上处理机运行的。

3.1 软件实现

单标志法、双标志先检查、双标志后检查、Peterson算法。

3.1.1 单标志法(存在的主要问题:违背“空闲让进”原则)

3.1.1.1 基本思想

单标志法(Single Flag Method)是一种简单的进程互斥实现方法,通常用于解决两个进程间的互斥问题。它基于一个标志变量来控制对临界区的访问,确保只有一个进程能进入临界区。 

算法思想: 一个进程在访问完临界区后会把使用临界区的权限转交给另一个进程。也就是说每个进程进入临界区的权限只能被另一个进程赋子。

3.1.1.2 单标志法的基本概念及执行流程

标志变量:使用一个共享的标志变量来表示一个进程是否正在访问临界区。
互斥机制:通过设置和检查标志变量来实现互斥,确保在任何时刻只有一个进程能够进入临界区。 

执行流程代码如下:

 执行流程:
turn 的初值为0,即刚开始只允许0号进程进入临界区。若 P1先上处理机运行,则会一直卡在 ⑤。直到 P1的时间片用完,发生调度,切换 P0上处理机运行。
代码 ① 不会卡住 P0,P0可以正常访问临界区,在 P0访问临界区期间即时切换回 P1,P1依然会卡在 ⑤。只有 P0 在退出区将 turn 改为1后,P1才能进入临界区。

3.1.1.3 特点
  1. 简单易懂:单标志法的实现和理解都比较简单,适用于两个进程间的互斥问题。

  2. 缺点

    • 不适用于更多进程:单标志法只适用于两个进程。如果有更多进程,单标志法的实现将变得复杂且难以维护。
    • 忙等待:进程在等待时会不断检查标志变量,可能导致忙等待,浪费CPU资源。
    • 无法解决饥饿问题:如果没有适当的机制,可能会导致某些进程一直无法获得进入临界区的机会。
    • 只能按 P0 → P1 → P0 →P1→.这样轮流访问。这种必须“轮流访问”带来的问题是,如果此时允许进入临界区的进程是 P0,而P0一直不访问临界区,那么虽然此时临界区空闲,但是并不允许P1访问【违反空闲让进的原则】。

3.1.2 双标志先检查法(违反了忙则等待原则)

 3.1.2.1 基本思想

      设置一个布尔型数组flag[ ],数组中各个元素用来标记各进程想进入临界区的意愿,比如“flag[0]=ture”意味着0号进程P0现在想要进入临界区。每个进程在进入临界区之前先检查当前有没有别的进程想进入临界区,如果没有,则把自身对应的标志flag[ i ]设为true,之后开始访问临界区。

3.1.2.2 基本概念及执行流程
  • 标志变量:使用两个标志变量flag[0]flag[1],分别表示进程P0和P1是否希望进入临界区。
  • 回退机制:通过设置标志变量来指示进程是否希望进入临界区,并通过检查另一个进程的标志变量来确保互斥。

执行流程代码如下: 

      若P0和P1两个进程并发执行,若按照 ①➄➁➅③➆..的顺序执行,P0和 P1将会同时访问临界区。因此,双标志先检查法的主要问题是: 违反“忙则等待”原则。

      原因在于,进入区的“检查”和“上锁”两个处理不是一气呵成的。“检查”后,“上锁”前可能发生进程切换。 

3.1.2.3 特点
  • 互斥性:只要一个进程在访问临界区,另一个进程就会被阻止,确保了互斥性。
  • 进程饥饿:该方法可能会导致进程饥饿问题,即一个进程可能会长时间无法获得进入临界区的机会。
  • 忙等待:进程在等待时会不断检查标志变量,导致忙等待,可能浪费CPU资源。
  • 公平性:在某些实现中,如果处理得当,可以避免某些进程长时间等待的情况,从而提高公平性。

3.1.3 双标志后检查法

3.1.3.1 算法思想

双标志先检查法的改版。前一个算法的问题是先“检查”后“上锁”,但是这两个操作又无法一气呵成,因此导致了两个进程同时进入临界区的问题。因此,人们又想到先“上锁”后“检查的方法,来避免上述问题。

3.1.3.2 执行流程代码 



若按照 ①⑤➁⑥...的顺序执行,P0和 P1将都无法进入临界区。因此,双标志后检查法虽然解决了“忙则等待”的问题,但是又违背了“空闲让进”和“有限等待原则,会因各进程都长期无法访问临界资源而产生“饥饿”现象。
两个进程都争着想进入临界区,但是谁也不让谁,最后谁都无法进入临界区。

3.1.4  Peterson算法

3.1.4.1 算法思想 

      结合双标志法、单标志法的思想。如果双方都争着想进入临界区,那可以让进程尝试“孔融让梨”(谦让)。做一个有礼貌的进程。
算法思想: Peterson算法通过两个共享变量和一个标志变量,协调两个进程对临界区的访问。它确保在任何时候,最多只有一个进程能够进入临界区,同时避免了“忙等待”问题。

3.1.4.2 算法步骤


进入区:1.主动争取;2.主动谦让;3.检查对方是否也想使用,且最后一次是不是自己说了“客气话”

原理分析

  • P0P1 想要进入临界区时,它们分别将自己的 flag[i] 设置为 true,表示自己准备进入临界区。
  • 然后它们会将 turn 设置为对方的值,表示让出优先权给对方。
  • 每个进程在进入临界区前都会检查对方的 flagturn 值:
    • 如果对方没有准备进入临界区(flag[j] == false),那么可以进入临界区。
    • 如果对方准备进入临界区,但轮到自己优先进入(turn != j),那么自己也可以进入。
    • 如果对方准备进入并且对方优先(flag[j] == true && turn == j),则进程会等待,直到条件改变。

我们还是使用小渣和老渣的例子来分析: 

3.1.4.3 两个进程并发运行时会带来什么后果

按不同顺序穿插执行会发生什么?
①②③⑥⑦⑧....
①⑥②③....
①③⑥⑦⑧....
①⑥②⑦⑧.....

假设按照①⑥②⑦⑧.....顺序执行,会发生什么结果呢?
 

3.1.4.4 Peterson算法的特点
  • 互斥性:通过两个进程的 flag 变量和 turn 变量,可以确保在任何时刻,最多只有一个进程能进入临界区。
  • 空闲让权:如果一个进程不打算进入临界区(flag[i] = false),则另一个进程可以立即进入临界区,而无需等待。
  • 有界等待:进程不会无限期等待进入临界区,系统保证在有限时间内每个进程都可以进入临界区。

优点

  • 简单实现:Peterson算法不依赖任何特殊的硬件指令或中断机制,仅通过共享变量实现进程间的同步。
  • 互斥保证:能够有效防止多个进程同时进入临界区,避免数据竞争和不一致的问题。
  • 公平性:没有进程会被无限期阻塞,保证了有限时间内进程的执行。

缺点

  • 仅适用于两个进程:Peterson算法仅适用于两个进程的互斥访问问题。如果进程数大于两个,算法需要扩展。
  • 忙等待:尽管Peterson算法解决了互斥问题,但它仍然需要等待循环(即“忙等待”),消耗 CPU 资源,效率不高。

总结

 Peterson 算法用软件方法解决了进程互斥问题,遵循了空闲让进、忙则等待、有限等待 三个原则,但是依然未遵循让权等待的原则。
Peterson 算法相较于之前三种软件解决方案来说,是最好的,但依然不够好。

3.2 软件实现方法总结

3.3 硬件实现

 虽然可以利用软件方法解决诸进程互斥进入临界区的问题,但有一定难度,并且存在很大的局限性,因而现在已很少采用。相应地,目前许多计算机已提供了一些特殊的硬件指令,允许对一个字中的内容进行检测和修正,或者是对两个字的内容进行交换等。可利用这些特殊的指令来解决临界区问题。

 3.3.1 中断屏蔽法

与原语的实现思想相同,即在某进程开始访问临界区到结束访问为止都不允许被中断,也就不能发生进程切换,因此也不可能发生两个同时访问临界区的情况 

      1.基本思想:关中断是实现互斥的最简单的方法之一。在进入锁测试之前关闭中断,直到完成锁测试并上锁之后才能打开中断。这样,进程在临界区执行期间,计算机系统不响应中断,从而不会引发调度,也就不会发生进程或线程切换。由此,保证了对锁的测试和关锁操作的连续性和完整性,有效地保证了互斥。
总结为一幅图,如下图所示: 

2.关中断的优缺点 

      该方法的优点是简单。 但是,关中断的方法存在许多缺点:0. 只适用于操作系统内核进程,不适用于用户进程(因为开/关中断指令只能运行在内核态,这组指令如果让用户随意使用会很危险)① 滥用关中断权力可能导致严重后果;② 关中断时间过长,会影响系统效率,限制了处理器交叉执行程序的能力;③ 关中断方法也不适用于多CPU 系统,因为在一个处理器上关中断并不能防止进程在其它处理器上执行相同的临界段代码。

3.关中断通常仅在以下场景中有效:

  • 单处理器系统:在早期的单处理器系统中,关中断是一种常见的实现互斥的方式,因为在单处理器环境下,关中断可以完全阻止中断,从而确保临界区的安全访问。

  • 操作系统内核代码:操作系统内核代码需要对硬件资源(如寄存器、缓冲区等)进行直接访问,并且可能需要在处理一些关键任务(如调度、驱动程序)时临时关闭中断。在这种情况下,关中断是合理的,因为它确保了操作系统能够控制对关键资源的独占访问。

4. 关中断为什么只适用于内核进程

关中断是一种比较粗放的同步机制,只有内核进程(或运行在内核态的代码)才能安全有效地使用它,原因包括以下几点:

  • 内核态权限:关中断需要较高的权限(内核态权限),因为中断是操作系统用来管理硬件和进程切换的重要机制。用户态进程通常没有权限直接控制中断。如果允许用户态进程关中断,可能会导致系统的不稳定和安全风险。

  • 影响系统整体性能:中断机制是操作系统中断点执行、响应外部设备、调度任务的重要手段。如果某个进程在用户态关中断,可能会导致整个系统无法响应外部事件(如键盘、网络或其他硬件设备的请求),这会影响整个系统的正常运行。

  • 影响实时性和响应性:如果操作系统无法及时响应中断,会降低系统的响应能力,尤其在实时系统中,可能会导致关键任务被延迟执行。而在多任务操作系统中,关中断会影响调度程序,使得其他进程无法执行。

  • 不适合多处理器系统:在多核处理器或多处理器系统中,关中断只能影响本处理器上的中断,但无法防止其他处理器上的进程访问临界区。因此,关中断这种方法在多处理器系统中效果有限,无法保证完全的互斥。

3.3.2 利用Test-and-Set指令实现互斥

      这是一种借助一条硬件指令【“测试并建立”指令TS(Test-and-Set)】以实现互斥的方法。在许多计算机中都提供了这种指令。在有的地方称为TestAndSetLock指令,或称TSL指令。

1. Test-and-Set指令的基本原理

      Test-and-Set指令通过硬件支持,确保对共享变量的读取修改操作是原子的,避免了并发情况下可能出现的竞态条件(Race Condition)。它通常被用来实现锁,保证只有一个进程或线程能进入临界区,而其他进程或线程在锁定的情况下会等待。

Test-and-Set指令可以简单理解为以下伪代码: 

 

 

如果 lock 原本是 false,Test-and-Set 操作将其设置为 true 并返回 false,while循环条件不满足,直接跳过循环,这意味着当前进程可以进入临界区,因为它成功获取了锁。

如果 lock 原本是 true,Test-and-Set 操作仍将 lock 设为 true 并返回 true,while循环条件满足,会一直循环,表示锁已经被其他进程或线程持有,当前进程需要等待。直到当前访问临界区的进程在退出区进行“解锁”。

2. 工作流程

假设有多个进程,Test-and-Set的流程如下:

  1. 进程想进入临界区:它执行 Test-and-Set 指令,检查并设置锁变量 lock

    • 如果锁是 false,进程设置 locktrue,并进入临界区。
    • 如果锁已经是 true,进程会继续忙等待,直到锁变为 false
  2. 进程执行临界区代码:只有一个进程能成功进入临界区,因为 Test-and-Set 是原子操作,其他进程会在忙等待循环中。

  3. 进程离开临界区:它将 lock 变量设为 false,其他等待的进程可以再次执行 Test-and-Set 指令,检查并获取锁。

3. Test-and-Set实现互斥锁示例

// 假设lock变量被初始化为false
bool lock = false;void acquire_lock() {while (TestAndSet(&lock)) {// 如果锁已经被其他进程持有,忙等待}
}void release_lock() {lock = false;  // 释放锁
}void critical_section() {acquire_lock();  // 获取锁// 进入临界区// ...release_lock();  // 离开临界区
}

在上面的代码中,acquire_lock() 会一直执行 TestAndSet() 操作,直到它成功获取到锁(lock == false 时进入临界区)。当临界区代码执行完毕后,通过 release_lock()lock 变量重新设为 false,允许其他进程进入临界区。 

4. Test-and-Set的特点

优点:

  • 简单易实现:Test-and-Set指令通过硬件支持,确保对共享变量的操作是原子的,逻辑上相对简单。
  • 原子性:Test-and-Set 是原子操作,能够在多处理器环境下保证互斥访问。
  • 适用于多核系统:由于 Test-and-Set 是硬件级的原子操作,它能在多核处理器中使用,确保多个核同时访问共享资源时的同步。

缺点:

  • 忙等待(Busy Waiting):如果锁已经被占用,其他进程会不断执行 Test-and-Set 操作,导致忙等待,消耗 CPU 资源。
  • 可能导致死锁或活锁:如果多个进程同时竞争锁资源且没有其他机制控制访问次序,可能会出现死锁或活锁的现象。
  • 公平性问题:Test-and-Set 操作没有内置的公平性机制,进程可能会长时间无法获取锁,导致饥饿现象。

5. Test-and-Set的应用场景

  • 内核态的锁实现:Test-and-Set常用于操作系统内核中实现简单的自旋锁(Spinlock),尤其在多处理器系统中,通过自旋等待来保证临界区的互斥。
  • 硬件同步原语:Test-and-Set是硬件级的同步原语,许多 CPU 指令集(如 x86、ARM)都提供了 Test-and-Set 指令,以支持多线程或多进程的并发控制。

6. 总结

      Test-and-Set 指令是一种硬件支持的原子操作,用于实现多进程或多线程之间的互斥。它能够保证在并发环境下对共享资源的安全访问,适用于内核态或操作系统中实现锁。然而,它的忙等待特性使得它不适用于高负载场景,现代系统往往使用信号量、互斥锁等更高效的同步机制来替代 Test-and-Set。

3.3.3 利用Swap指令实现进程互斥

      Swap指令是一种经典的同步原语,用于实现多进程或多线程之间的互斥同步。与 Test-and-Set指令 类似,Swap指令通过硬件支持,确保对共享变量的操作是原子的,从而避免竞态条件。它通常用于构建低级别的锁机制,保证共享资源的互斥访问。

      该指令称为对换指令,在Intel 80x86中又称为XCHG指令,用于交换两个字的内容。

1. Swap指令的基本原理

Swap指令的核心是交换两个变量的值,并确保交换操作是原子的,即整个交换过程不能被中断或打断。

Swap指令的伪代码如下:

void Swap(bool *a, bool *b) {bool temp = *a;*a = *b;*b = temp;
}
  • a 表示锁的状态,如果锁是 false,表示没有进程持有锁,临界区可进入;
  • b 是一个变量。

      通过这种交换操作,进程能以原子的方式检查并修改锁的状态,确保其他进程不能同时访问临界区。

 

在获取锁的过程中,Swap操作会将 lockb/old 进行原子的交换:

  • 如果 lock 之前是 false,表示没有其他进程持有锁,交换后 lock 变为 true,而 b 变为false,这意味着当前进程成功获取锁,进入临界区。
  • 如果 lock 之前是 true,表示已经有其他进程持有锁,交换后 lock 依旧为 true,而 b 依旧为 true,这意味着当前进程没有获取锁,需要继续忙等待。

2. Swap指令的特点

优点:

  • 原子性:Swap指令是硬件支持的原子操作,能够保证多处理器系统中的互斥访问,即使有多个处理器同时执行,也能确保共享变量的正确更新。
  • 简单性:Swap指令的逻辑相对简单,适合用于实现低级别的锁机制。
  • 硬件支持:许多处理器架构(如 x86、ARM)提供了 Swap指令,用于操作系统或应用程序中的锁实现。

缺点:

  • 忙等待(Busy Waiting):如果锁已经被其他进程持有,进程会在循环中执行 Swap 操作,导致忙等待,消耗 CPU 资源。
  • 可能导致死锁或活锁:多个进程如果同时竞争锁资源,可能会出现活锁现象,即进程不停交换锁的状态,却无法实际进入临界区。
  • 不公平性:Swap指令没有内置公平性机制,可能导致某些进程长时间无法获得锁,出现饥饿现象。

3. Swap指令的应用场景

  • 操作系统内核中的锁实现:Swap指令通常用于操作系统内核中实现自旋锁(Spinlock)或其他低级别的同步机制。在内核态中,锁的持有时间一般较短,忙等待的开销可以被接受。
  • 多处理器系统中的同步:Swap指令适合用于多处理器环境,因为它是硬件原子操作,能够保证多个处理器对共享资源的安全访问。

4. 总结

      Swap指令是一种硬件级的原子操作,用于实现多进程或多线程的互斥访问。它通过交换锁变量的值来实现对共享资源的互斥访问,确保进程间的同步。尽管 Swap指令提供了简单有效的同步机制,但由于忙等待问题,它在现代系统中被更加高级的同步机制(如互斥锁、信号量等)所取代。不过,它在操作系统内核和硬件同步中依然有重要的应用。

 

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

进程间的通信 2 消息队列

system V IPC IPC : Inter-Process Communication (进程间通讯) System V IPC 对象共有三种: 消息队列共享内存信号量 System V IPC 是由内核维护的若干个对象,通过ipcs命名查询 每个 IPC 对象都有一个唯一的 ID,可以通过ftok()函数生成 …

使用SoapUI、Postman工具调用Webservice方法

SoapUI工具更适合调用Webservice使用。 1.使用SoapUI工具调用Webservice 创建“New SOAP Project” 自行定义一个项目名称,输入wsdl地址: 在左侧列表找到方法名,双击“Request 1”, 在请求数据中,添加对应的参数,然…

Linux--禁止root用户通过ssh直接登录

原文网址:Linux--禁止root用户通过ssh直接登录_IT利刃出鞘的博客-CSDN博客 简介 本文介绍Linux服务器怎样禁止root用户通过ssh直接登录。 为什么要禁止? 因为root用户是每个Linux系统都有的,黑客可以使用root用户名尝试不同的密码来暴力破…

【笔记】自动驾驶预测与决策规划_Part3_路径与轨迹规划

文章目录 0. 前言1. 基于搜索的路径规划1.1 A* 算法1.2 Hybrid A* 算法 2. 基于采样的路径规划2.1 Frent Frame方法2.2 Cartesian →Frent 1D ( x , y ) (x, y) (x,y) —> ( s , l ) (s, l) (s,l)2.3 Cartesian →Frent 3D2.4 贝尔曼Bellman最优性原理2.5 高速轨迹采样——…

ETHERCAT转PROFIENT网关—迅捷伺服驱动器数据交互

在当前的生产现场中,PLC 控制器与迅捷伺服驱动器之间通过通讯方式进行连接的情况愈发频繁。有些现场中,控制器和伺服驱动器采用统一的通讯协议,然而在另一些现场,会出现伺服驱动器 站使用不同协议的情况,这主要是由于不…

小阿轩yx-通过state模块定义主机状态

小阿轩yx-通过state模块定义主机状态 前言 前面学习了远程执行模块,这些模块的执行类似语段 shell 脚本,每次执行都会触发一次相同的功能,在大量的 minion 上运行远程命令当然是重要的,但是对于 minion 的环境控制,使…

利用 ARMxy边缘计算网关和 BLiotlink 软网关,实现工业智能化升级

在当今数字化、智能化的时代浪潮中,工业领域也在不断寻求创新与突破,以提高生产效率、降低成本并提升竞争力。ARM 工业计算机与 BLiotlink 协议转换软件的结合,为工业智能化带来了新的机遇和解决方案。 一、ARM 工业计算机的优势 ARM 工业计…

怎么找到抖音爆款内容,进行扩散传播?

企业如果想做好抖音平台的品牌营销,需要时刻监测抖音爆款内容并进行加热放大,据此快速创新和改进内容,才能短期提高品牌相关内容的曝光量,快速拉升品牌声量。怎么去找到抖音的爆款内容或者是值得品牌关注的优质内容,主…

Active Directory 实验室设置第一部分- AD林安装

在之前的文章中,已经讨论了活动目录的基本知识。在这篇文章中,我们将讨论如何设置和配置环境,以便我们可以使用它来执行各种攻击方案和检测。我们将讨论如何通过GUI和CLI方式完成。 # 1、Active Directory 设置 让我们从活动目录实验室设置…

统计项目代码行数工具—cloc

目录 引言一、cloc简介二、cloc安装三、cloc使用四、参考博客 引言 项目开发完成,想要查看自己项目的代码行数,强烈推荐一款非常好用的命令行工具-cloc。 一、cloc简介 只需要通过命令行的方式运行cloc,就可以得知指定文件代码行数、注释函…

AI大模型之旅-langchain结合glm4,faiss构建本地知识库

所需依赖如下: _libgcc_mutex0.1main _openmp_mutex5.11_gnu accelerate0.34.2pypi_0 aiofiles23.2.1pypi_0 aiohappyeyeballs2.4.0pypi_0 aiohttp3.10.5pypi_0 aiosignal1.3.1pypi_0 annotated-types0.7.0pypi_0 anyio4.4.0pypi_0 attrs24.2.0pypi_0 bitsandbytes…

Leetcode面试经典150题-172.阶乘后的零

给定一个整数 n ,返回 n! 结果中尾随零的数量。 提示 n! n * (n - 1) * (n - 2) * ... * 3 * 2 * 1 示例 1: 输入:n 3 输出:0 解释:3! 6 ,不含尾随 0示例 2: 输入:n 5 输出&a…

线程池总结

线程池的执行流程总结: 从创建线程池的参数分析: 1.提交新线程,线程池会在线程池中分配一个空闲线程,用于执行线程任务。 2.参数(int corePoolSize):核心线程数 如果线程池中不存在空闲线程,则线程池会判…

ADB 安装教程:如何在 Windows、macOS 和 Linux 上安装 Android Debug Bridge

目录 一、ADB 介绍 二、Windows 系统安装 ADB 1. 下载 ADB 2. 解压文件 3. 验证 ADB 安装 4. 配置环境变量 5. 验证全局 ADB 使用 三、macOS 系统安装 ADB 1. 下载 ADB 2. 解压文件 3. 配置环境变量 4. 验证 ADB 安装 四、Linux 系统安装 ADB 1. 使用包管理器安装…

【UE5】将2D切片图渲染为体积纹理,最终实现使用RT实时绘制体积纹理【第二篇-着色器制作】

在上一篇文章中,我们已经理顺了实现流程。 接下来,我们将在UE5中,从头开始一步一步地构建一次流程。 通过这种方法,我们可以借助一个熟悉的开发环境,使那些对着色器不太熟悉的朋友们更好地理解着色器的工作原理。 这篇…

MySQL 主从复制部署与优化

文章目录 前言 在现代数据库管理中,MySQL 主从复制是一种关键技术,用于提高数据的可用性和性能。随着 Docker 容器技术的普及,利用 Docker 搭建 MySQL 主从复制环境已成为一种趋势,它提供了一种简便、高效且可扩展的解决方案。本…

LED 生产电子看板实现工厂精准管理

在当今竞争激烈的制造业领域,工厂的管理效率和精度直接关系到企业的生存与发展。而 LED 生产电子看板的出现,为工厂实现精准管理带来了全新的解决方案。 一、电子看板能够实现对生产进度的精准把控 在传统的工厂管理中,生产进度的了解往往依…

协同编程的艺术:SIDE 让团队协作更上一层楼

一、协同编程的现状 在当前软件开发中,团队协作面临着诸多挑战。沟通不畅常常导致项目进度延迟,版本控制复杂使得代码合并困难重重。传统 IDE 在协同工作方面存在明显的局限性,缺乏实时协作功能,团队成员之间的沟通工具也不够完善…

个人小结(2.0)

离谱,困扰着几周的问题今天偶然发现了解决方法。 问题如下:就是对应的模块引入爆红,但是单击进入引入的文件没有问题 然后它的提示是: 无法找到模块“../views/screen/index.vue”的声明文件。“c:/Users/10834/Desktop/0716_pro…

班主任群发成绩教程,宝藏工具来减负

今天想和大家聊聊班主任的那些事儿。当班主任可真不是一件轻松的工作啊。要备课吧,得精心设计每一个教学环节,从教学目标到教学方法,从课程导入到课后作业,每个细节都得考虑周全。 还要管理班级纪律,处理同学之间的小摩…