多处理机操作系统:进程同步

目录

一.集中式与分布式同步方式

1.集中式同步

2.分布式同步

二.自旋锁

1.自旋锁的特点

2.自旋锁的缺点

3.自旋锁示例(伪代码)

三.读-复制-更新锁

1.RCU锁的特点

2.RCU锁的缺点

3. RCU锁示例(伪代码)

三.二进制数补偿算法和待锁 CPU 等待队列机构

二进制数补偿算法 

1.概述:

2.优点:

3.缺点:

待锁 CPU 等待队列机制 (Lock-Queue-Wait)

1.概述:

2.优点:

3.缺点:

四.定序机构

1. 为什么要使用定序机构?

2. 定序机构的类型

3. 定序机构的应用

五.面包房算法

1.概述

2.算法原理

3.算法实现

分析

适用场景

六.令牌环算法

概述

算法原理

优点

缺点

应用场景

示例

分析


        在多处理机系统中,多个处理器可以同时执行多个进程,这使得进程同步成为了一个关键问题。进程同步是指协调多个进程执行顺序和访问共享资源的方式,以确保数据一致性和避免冲突。本文将探讨多处理机操作系统中的各种进程同步机制和算法。

一.集中式与分布式同步方式

        多处理机操作系统中的进程同步方式可以分为集中式同步和分布式同步两种。每种方式在实现和应用上都有其优点和缺点,适用于不同的场景和需求。

1.集中式同步

概述

  • 集中式同步方式采用一个中央同步机构来协调所有进程的执行。所有进程对共享资源的访问请求都发送到中央同步机构,由它来控制访问顺序。

优点

  1. 实现简单:由于所有同步操作都集中在一个地方,管理和控制相对简单。
  2. 一致性保障:中央同步机构可以确保所有进程对共享资源的访问顺序,避免数据冲突和不一致问题。

缺点

  1. 单点瓶颈:中央同步机构可能成为系统的瓶颈,影响整体性能。如果中央机构处理请求的速度跟不上进程的请求速度,系统性能会显著下降。
  2. 可靠性问题:如果中央同步机构出现故障,会导致整个系统的同步机制失效,影响系统的稳定性和可靠性。

应用场景

  • 小规模多处理机系统:如多核处理器中的共享内存同步。
  • 需要严格一致性的系统:如事务处理系统中的锁管理。

示例

假设有一个共享资源需要被多个进程访问,使用集中式同步机制的伪代码如下:

class CentralSync:def __init__(self):self.lock = threading.Lock()def request_access(self, process_id):self.lock.acquire()print(f"Process {process_id} is accessing the resource")def release_access(self):print("Resource is released")self.lock.release()central_sync = CentralSync()def process_task(process_id):central_sync.request_access(process_id)# Critical sectiontime.sleep(random.uniform(0.1, 0.5))central_sync.release_access()threads = []
for i in range(5):t = threading.Thread(target=process_task, args=(i,))threads.append(t)t.start()for t in threads:t.join()
2.分布式同步

概述

  • 分布式同步方式中,每个处理器都有自己的同步机构,进程之间的同步由它们自行协调。分布式同步减少了对中央同步机构的依赖,提高了系统的可扩展性。

优点

  1. 高可扩展性:由于没有单一的中央同步机构,系统可以更容易地扩展,处理更多的进程和共享资源。
  2. 减少单点瓶颈:每个处理器独立处理同步请求,避免了单点瓶颈问题,提高了系统性能。
  3. 提高可靠性:分布式同步避免了中央机构故障导致的全系统失效问题,提高了系统的可靠性。

缺点

  1. 实现复杂:进程之间的同步需要更多的协调和通信机制,增加了实现的复杂性。
  2. 一致性问题:需要额外的机制确保多个处理器之间的一致性,避免数据冲突和不一致问题。

应用场景

  • 大规模分布式系统:如分布式数据库、分布式文件系统。
  • 高并发应用:如大规模互联网服务、云计算平台。

示例

假设在分布式系统中,每个节点都有自己的同步机构,使用分布式同步机制的伪代码如下:

 

import threading
import time
import randomclass DistributedSync:def __init__(self):self.locks = {}def request_access(self, process_id, resource_id):if resource_id not in self.locks:self.locks[resource_id] = threading.Lock()self.locks[resource_id].acquire()print(f"Process {process_id} is accessing resource {resource_id}")def release_access(self, resource_id):if resource_id in self.locks:print(f"Resource {resource_id} is released")self.locks[resource_id].release()distributed_sync = DistributedSync()def process_task(process_id, resource_id):distributed_sync.request_access(process_id, resource_id)# Critical sectiontime.sleep(random.uniform(0.1, 0.5))distributed_sync.release_access(resource_id)threads = []
for i in range(5):t = threading.Thread(target=process_task, args=(i, i % 2)) # Accessing two different resourcesthreads.append(t)t.start()for t in threads:t.join()

二.自旋锁

        自旋锁是一种常用的同步机制,用于在多处理器环境下控制对共享资源的访问。当一个进程尝试获取锁时,如果锁已被其他进程持有,则该进程不会被挂起,而是进入自旋状态,不断循环等待直到锁被释放。自旋锁适合锁被持有时间较短的情况,可以避免挂起进程并调度其他进程的额外开销。

1.自旋锁的特点
  1. 简单实现:自旋锁的实现通常较为简单,主要依赖于硬件提供的原子操作(如Test-and-Set、Compare-and-Swap等)。

  2. 短锁持有时间:自旋锁适用于锁被持有时间较短的场景。在这种情况下,自旋等待不会产生明显的性能影响。

  3. 高频率锁访问:自旋锁适合高频率锁访问的场景,因为它避免了过程中频繁的上下文切换。

  4. 避免进程挂起:自旋锁不会将等待的进程挂起,而是保持自旋等待状态。这减少了调度开销和进程切换时间。

2.自旋锁的缺点
  1. 忙等待:自旋锁使用忙等待的方式获取锁,消耗CPU资源。如果锁被长时间持有,自旋锁可能导致性能下降。

  2. 不适合长时间锁持有:对于锁持有时间较长的情况,自旋锁不适用,因为自旋等待会浪费大量的CPU时间。

3.自旋锁示例(伪代码)
lock = 0; // 0表示锁未被持有,1表示锁被持有void acquire_lock() {while (atomic_test_and_set(&lock, 1)) {// 自旋等待,直到锁被释放}
}void release_lock() {lock = 0; // 释放锁
}

三.读-复制-更新锁

        RCU锁是一种为频繁读少写的共享数据设计的同步机制。它允许多个进程同时读取数据,而写数据的进程需要先复制数据,然后再进行修改。这可以确保读进程可以不受干扰地访问数据,同时写进程也不会阻塞读进程。

1.RCU锁的特点
  1. 高效读操作:RCU锁允许多个读进程同时读取数据,而不需要互斥锁。这提高了读操作的性能和并发性。

  2. 复制更新:写进程在更新数据前,先复制一份数据进行修改。修改完成后,使用指针替换旧数据,实现更新。

  3. 延迟回收:RCU锁使用延迟回收机制,在所有读进程都完成对旧数据的访问后,才回收旧数据的内存。这确保了读进程访问的一致性。

  4. 适用于读多写少:RCU锁非常适用于读多写少的场景,如操作系统内核数据结构、路由表等。

2.RCU锁的缺点
  1. 写操作复杂:写操作需要复制数据并更新指针,过程相对复杂。

  2. 内存占用增加:在读进程较多的情况下,旧数据的延迟回收可能导致内存占用增加。

3. RCU锁示例(伪代码)
data = new_data(); // 新数据副本void rcu_read_lock() {// 读锁,标志读操作开始rcu_read_count++;
}void rcu_read_unlock() {// 读锁,标志读操作结束rcu_read_count--;
}void rcu_synchronize() {// 等待所有读进程完成读操作while (rcu_read_count > 0) {// 自旋等待}
}void rcu_update(data_t *new_data) {rcu_synchronize(); // 确保所有读操作完成old_data = data; // 旧数据data = new_data; // 替换为新数据free(old_data); // 释放旧数据
}

三.二进制数补偿算法和待锁 CPU 等待队列机构

二进制数补偿算法 

1.概述


        二进制数补偿算法是一种用于避免死锁和饥饿的同步机制。每个进程都有一个二进制数,当一个进程请求一个锁时,会检查所有其他进程的二进制数。如果其他进程的二进制数较小,则允许该进程获取锁;否则,该进程进入等待队列。这样可以确保所有进程都有机会获取锁,避免饥饿情况的发生。

2.优点

  1. 避免饥饿:通过检查和比较二进制数,确保所有进程都有机会获取锁,避免某些进程长期无法获取锁的情况。
  2. 解决死锁:通过严格的次序控制,避免死锁的发生。

3.缺点

  1. 实现复杂:需要额外的机制来管理和比较每个进程的二进制数。
  2. 性能开销:二进制数的检查和比较会增加一些性能开销。

应用场景
适用于需要严格控制锁获取次序,避免饥饿和死锁的高并发环境。

示例

以下是一个简单的二进制数补偿算法的伪代码示例:

import threading
import timeclass BinaryCompensationLock:def __init__(self):self.lock = threading.Lock()self.queue = []self.current_binary_number = 0def acquire(self, process_id):with self.lock:binary_number = self.current_binary_numberself.queue.append((process_id, binary_number))self.queue.sort(key=lambda x: x[1])self.current_binary_number += 1while self.queue[0][0] != process_id:self.lock.release()time.sleep(0.01)self.lock.acquire()def release(self):with self.lock:self.queue.pop(0)binary_compensation_lock = BinaryCompensationLock()def process_task(process_id):binary_compensation_lock.acquire(process_id)# Critical sectionprint(f"Process {process_id} is in critical section")time.sleep(1)binary_compensation_lock.release()threads = []
for i in range(5):t = threading.Thread(target=process_task, args=(i,))threads.append(t)t.start()for t in threads:t.join()

待锁 CPU 等待队列机制 (Lock-Queue-Wait)

1.概述


待锁 CPU 等待队列机制是一种同步机制,当一个处理器请求一个锁时,如果锁已被其他处理器持有,则该处理器进入等待队列。当锁被释放时,等待队列中的下一个处理器被唤醒并获取锁。这样的机制可以避免处理器忙等待,提高系统效率。

2.优点

  1. 避免忙等待:处理器在等待锁时不会一直占用CPU,而是进入等待队列,释放CPU资源。
  2. 提高系统效率:通过等待队列机制,可以更高效地管理锁的分配和处理器资源。

3.缺点

  1. 实现复杂:需要额外的数据结构和机制来管理等待队列。
  2. 上下文切换开销:等待处理器的唤醒和上下文切换会增加一些开销。

应用场景
适用于多处理器系统中的高并发环境,需要避免忙等待,提高资源利用效率。

示例

以下是一个简单的待锁 CPU 等待队列机制的伪代码示例:

import threading
import queue
import timeclass LockQueueWait:def __init__(self):self.lock = threading.Lock()self.wait_queue = queue.Queue()def acquire(self):self.lock.acquire()if self.lock.locked():self.wait_queue.put(threading.current_thread())self.lock.release()while threading.current_thread() != self.wait_queue.queue[0]:time.sleep(0.01)self.lock.acquire()else:self.lock.release()def release(self):if not self.wait_queue.empty():self.wait_queue.get()self.lock.release()lock_queue_wait = LockQueueWait()def process_task(process_id):lock_queue_wait.acquire()# Critical sectionprint(f"Process {process_id} is in critical section")time.sleep(1)lock_queue_wait.release()threads = []
for i in range(5):t = threading.Thread(target=process_task, args=(i,))threads.append(t)t.start()for t in threads:t.join()

 

四.定序机构

        定序机构(Ordering Mechanism)是计算机系统中一种重要的机制,用于确保多个处理器以正确的顺序执行指令。它通常通过在处理器之间发送消息来实现,以协调它们的执行顺序。这对于保证程序的正确性至关重要,特别是在有内存共享的系统中。

 

1. 为什么要使用定序机构?

        在多处理器系统中,多个处理器可以并行执行指令。如果没有定序机构,处理器可能会在未完成依赖操作的情况下执行指令,导致程序行为不可预测甚至出现错误。例如,如果处理器 A 正在写入一个共享变量,处理器 B 在读取该变量之前就读取了它,那么处理器 B 读取到的值将是错误的。

        使用定序机构可以避免这些问题,因为它可以确保处理器按照正确的顺序执行指令,并完成所有依赖操作。

 

2. 定序机构的类型

定序机构有多种类型,它们在实现方式和性能上有所不同。常见类型的定序机构包括:

  • 程序顺序 (Program Order): 程序顺序是最简单的定序机构,它确保处理器按照程序文本的顺序执行指令。但是,程序顺序无法利用指令之间的并行性,因此效率较低。
  • 弱一致性 (Weak Consistency): 弱一致性允许处理器在不违反程序顺序的情况下重新排序指令。这可以提高性能,但会使程序的调试更加困难。
  • 强一致性 (Strong Consistency): 强一致性确保处理器看到的内存状态与程序顺序一致。这使得程序的调试更加容易,但会降低性能。
  • 锁 (Lock): 锁是一种显式的定序机制,它允许程序员控制多个处理器对共享资源的访问。锁可以提高性能,但如果使用不当,会导致死锁等问题。
  • 栅栏 (Barrier): 栅栏是一种用于强制处理器同步的定序机制。所有处理器必须到达一个栅栏才能继续执行。栅栏可以用于确保多个处理器在完成特定操作之前不再执行。

 

3. 定序机构的应用

定序机构在计算机系统的各个层级都有应用,包括:

  • 处理器架构: 处理器架构通常包含定序机构,用于控制处理器内部的不同执行单元之间的指令执行顺序。
  • 操作系统: 操作系统通常包含定序机构,用于协调多个处理器对内存和其他资源的访问。
  • 应用程序: 应用程序可以使用定序机构来控制多线程之间的指令执行顺序。

 

五.面包房算法

1.概述

        面包房算法(Bakery Algorithm)是由Leslie Lamport提出的一种用于避免死锁的分布式同步算法。该算法以面包店排队购买面包为喻,每个进程都有一个唯一的编号,当多个进程尝试获取同一个锁时,编号较小的进程优先获取锁。这种编号机制可以保证公平性,避免死锁和饥饿问题。

2.算法原理

面包房算法的基本思路是,每个进程在进入临界区之前,先“拿一个数字”,然后按照数字的顺序进入临界区。具体步骤如下:

  1. 进程获取号票

    • 每个进程请求进入临界区时,首先获取一个号票。这个号票是一个唯一的编号,表示该进程的优先级。
  2. 等待顺序到达

    • 进程在获取号票后,检查其他所有进程的号票,确保自己是当前最小的号票,才可以进入临界区。
  3. 进入临界区

    • 当进程确定自己的号票是最小的并且没有其他进程在进入临界区时,它可以进入临界区。
  4. 释放临界区

    • 进程完成临界区的任务后,释放号票,让其他进程可以继续进入。

3.算法实现

面包房算法的伪代码如下:

import threading
import timeclass BakeryAlgorithm:def __init__(self, n):self.n = nself.choosing = [False] * nself.number = [0] * ndef max_number(self):return max(self.number)def lock(self, process_id):self.choosing[process_id] = Trueself.number[process_id] = self.max_number() + 1self.choosing[process_id] = Falsefor i in range(self.n):while self.choosing[i]:passwhile self.number[i] != 0 and (self.number[i] < self.number[process_id] or (self.number[i] == self.number[process_id] and i < process_id)):passdef unlock(self, process_id):self.number[process_id] = 0def critical_section(process_id):print(f"Process {process_id} is in critical section")time.sleep(1)  # 模拟临界区操作print(f"Process {process_id} is leaving critical section")def process_task(bakery, process_id):while True:bakery.lock(process_id)critical_section(process_id)bakery.unlock(process_id)time.sleep(1)  # 模拟非临界区操作if __name__ == "__main__":n = 5bakery = BakeryAlgorithm(n)threads = []for i in range(n):t = threading.Thread(target=process_task, args=(bakery, i))threads.append(t)t.start()for t in threads:t.join()
分析

优点

  1. 避免死锁:面包房算法通过唯一编号机制,确保所有进程都能公平地获取锁,避免死锁和饥饿问题。
  2. 简单实现:相对其他复杂的分布式同步算法,面包房算法的实现较为简单。

缺点

  1. 性能开销:在进程数较多时,获取号票和比较号票的操作可能增加系统开销。
  2. 不适用于高实时性要求的场景:由于需要等待其他进程的号票,可能导致高延迟,不适合高实时性的应用场景。

适用场景

面包房算法适用于需要确保进程公平性和避免死锁的分布式系统,特别是在多进程并发访问共享资源的环境中,如:

  • 多线程编程中的临界区保护。
  • 分布式系统中的资源分配。

 

六.令牌环算法

概述

        令牌环算法是一种用于分布式同步的算法,常用于保证多个处理器或节点之间的同步和公平性。该算法使用一个令牌(Token)在处理器之间传递,只有持有令牌的处理器才能执行临界区代码。令牌按照一定的顺序在处理器之间传递,确保每个处理器都有机会进入临界区,从而避免死锁和饥饿问题。

算法原理
  1. 令牌初始化

    • 系统初始化时,创建一个唯一的令牌,并将其赋予某个处理器。
  2. 令牌传递

    • 持有令牌的处理器可以执行临界区代码。
    • 执行完临界区代码后,该处理器将令牌传递给下一个处理器。
    • 如果一个处理器没有临界区代码要执行,它直接将令牌传递给下一个处理器。
  3. 循环传递

    • 令牌在处理器之间按照固定顺序循环传递,确保所有处理器都有机会获取令牌。

优点
  1. 避免死锁和饥饿:令牌环算法通过令牌顺序传递,确保每个处理器都有机会获取令牌,避免死锁和饥饿情况。
  2. 公平性:每个处理器按顺序轮流获取令牌,保证了访问临界区的公平性。
  3. 简单实现:令牌环算法的概念和实现相对简单,适合分布式系统。

缺点
  1. 令牌丢失问题:如果令牌在传递过程中丢失,系统需要额外机制检测和恢复令牌。
  2. 延迟问题:令牌传递需要时间,处理器在等待令牌时会产生一定的延迟,尤其在处理器数量较多时。

应用场景

令牌环算法适用于需要公平访问共享资源的分布式系统,例如:

  • 局域网协议(如令牌环网络协议)。
  • 分布式数据库系统。
  • 分布式文件系统。

示例

以下是一个简单的令牌环算法伪代码示例:

import threading
import time# 初始化处理器数量和令牌
num_processors = 5
token = threading.Lock()
token_holder = 0def processor_task(process_id):global token_holderwhile True:# 等待令牌while token_holder != process_id:time.sleep(0.01)# 模拟临界区操作with token:print(f"Processor {process_id} is in critical section")time.sleep(1)  # 临界区操作print(f"Processor {process_id} is leaving critical section")# 传递令牌给下一个处理器token_holder = (token_holder + 1) % num_processorstime.sleep(1)  # 模拟非临界区操作# 创建并启动线程
threads = []
for i in range(num_processors):t = threading.Thread(target=processor_task, args=(i,))threads.append(t)t.start()# 等待所有线程完成
for t in threads:t.join()
分析

工作流程

  1. 每个处理器在循环中等待令牌。
  2. 一旦获取到令牌,处理器进入临界区执行任务。
  3. 完成临界区任务后,处理器将令牌传递给下一个处理器。
  4. 重复上述过程,确保所有处理器都有机会进入临界区。

注意事项

  • 令牌的初始化:需要在系统初始化时生成唯一令牌,并赋予某个处理器。
  • 令牌恢复机制:需要设计令牌丢失检测和恢复机制,以应对令牌在传递过程中丢失的情况。

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

国外开源字典集(wordlists)

Assetnote Wordlists Wordlists that are up to date and effective against the most popular technologies on the internet.https://wordlists.assetnote.io/

opencv c++ 检测图像尺寸大小,标注轮廓

1. 项目背景 本项目旨在开发一个图像处理程序&#xff0c;通过使用计算机视觉技术&#xff0c;能够自动检测图像中物体的尺寸并进行分类。项目利用了开源的计算机视觉库 OpenCV&#xff0c;实现了图像的灰度处理、二值化、轮廓检测、边界框绘制以及尺寸分类等功能。通过这些功…

区块链学习记录02

区块链女巫&#xff1a; 在区块链和加密货币的术语中&#xff0c;“女巫攻击”&#xff08;Sybil Attack&#xff09;是指一个恶意用户通过创建多个虚假身份来操纵网络的行为。这个名字来源于一位多重人格患者的故事。 具体来说&#xff0c;女巫攻击可能会对区块链网络造成以…

在智星云租用算力时,如何选择适合的GPU?

智星云平台分配GPU、CPU、内存的机制为&#xff1a;按租用的GPU数量成比例分配CPU和内存&#xff0c;算力市场显示的CPU和内存均为每GPU分配的CPU和内存&#xff0c;如果租用两块GPU&#xff0c;那么CPU和内存就x2。此外GPU非共享&#xff0c;每个实例对GPU是独占的。 一. CPU…

封装Redis工具类(解决击穿,穿透)

基于StringRedisTemplate封装一个缓存工具类 Redis实战篇 | Kyles Blog (cyborg2077.github.io) 目录 方法1&#xff1a;将任意Java对象序列化为JSON&#xff0c;并存储到String类型的Key中&#xff0c;并可以设置TTL过期时间 方法2&#xff1a;将任意Java对象序列化为JSON&a…

NSSCTF-Web题目12

目录 [SWPUCTF 2021 新生赛]finalrce 1、题目 2、知识点 3、思路 [UUCTF 2022 新生赛]ez_rce 1、题目 2、知识点 3、思路 [羊城杯 2020]easycon 1、题目 2、知识点 3、思路 [SWPUCTF 2021 新生赛]finalrce 1、题目 2、知识点 命令执行&#xff0c;tee命令 3、思路…

深度学习算法informer(时序预测)(三)(Encoder)

一、EncoderLayer架构如图&#xff08;不改变输入形状&#xff09; 二、ConvLayer架构如图&#xff08;输入形状中特征维度减半&#xff09; 三、Encoder整体 包括三部分 1. 多层EncoderLayer 2. 多层ConvLayer 3. 层归一化 代码如下 class AttentionLayer(nn.Module):de…

学习Vue 3中的浅拷贝与数组操作

学习Vue 3中的浅拷贝与数组操作 一、前言1.什么是浅拷贝&#xff1f;2.为什么需要浅拷贝&#xff1f;3.在Vue 3中使用浅拷贝进行数组操作3.1使用展开运算符进行浅拷贝3.2使用push方法添加新内容 4.注意事项5.结语 一、前言 在Vue 3应用程序开发中&#xff0c;我们经常需要对数…

淘宝扭蛋机小程序:互联网时代下行业的发展动力

近几年&#xff0c;扭蛋机在潮玩市场风靡&#xff0c;与各类IP合作&#xff0c;推出各种新颖有趣的扭蛋商品&#xff0c;吸引了众多的IP粉丝&#xff0c;他们会通过扭蛋机进行抽奖&#xff0c;获得喜欢的商品。 目前&#xff0c;移动应用程序不断升级优化&#xff0c;“互联网…

idea中的git在clone文件提示 filename too long

一 解决版本 1.1 问题描述以及解决办法 当在Windows系统下使用Git时出现“filename too long”错误&#xff1a; git config --system core.longpaths true

思科ospf+rip重发布配置命令

——————————————————————————————————————————— 基础配置 R1 Router>en #进入配置模式 Router#conf #进入配置模式 Router(config)#h…

如何在 MySQL 中创建和使用事务?

目录 1. 环境准备 2. 创建事务 3. 事务执行 4. 事务撤消 5. 总结 事务是数据库区别于文件系统的重要特征之一&#xff0c;当我们有了事务就会让数据库始终保持一致&#xff0c;同时我们还能通过事务机制恢复到某个时间点&#xff0c;这样可以保证已提交到数据库的修改不会…

人工智能在肿瘤检测以及癌症早筛中的最新研究|顶刊速递·24-06-21

小罗碎碎念 推文主题&#xff1a;人工智能在癌症检测以及早筛中的最新研究进展 之前有一篇推文介绍了哈佛发表的3D病理&#xff0c;当时应该有不少老师/同学对于数据的获取是有些懵的&#xff0c;那么今天你在第一篇文章中或许能找到答案。 一直看我推送的&#xff0c;并且不跳…

骁龙相机启动流程分析

一、骁龙相机启动流程分析 1. 相机启动阶段关键TAG 关键字解释deliverInputEvent点击事件bindApplicationApp 冷启动 创建applicationactivityStart创建camera activityactivityResumecamera UI界面开始显示connectDevicecameraFWK 开始链接并open sensorCameraHal::openSessio…

发那科 偏移实现三维码垛

1: OVERRIDE5% ;2: UFRAME_NUM0 ;3: UTOOL_NUM2 ;4: CALL TOOL_OFF ;5:J P[1:home] 30% FINE ;6: FOR R[3]0 TO 2 ;7: FOR R[1]0 TO 1 ;8: FOR R[2]0 TO 3 ;9: PR[5:偏移]LPOS-LPOS ;10: PR[5,3:偏移](PR[5,3:偏移]-5*(R[1]*4R[2]R[3]*8)) ;11: OFFSET COND…

MySQL系列-安装配置使用说明(MAC版本)

1、前言 本文将介绍MySQL的安装配置以及基本语法操作说明 环境&#xff1a;mac 版本&#xff1a;MySQL 8.0.28 之前电脑安装卸载过&#xff0c;后面在装的时候遇到一些问题&#xff0c;用了四五天才解决&#xff0c;主要是参考 https://blog.csdn.net/zz00008888/article/deta…

大厂晋升学习方法一:海绵学习法

早晨 30 分钟 首先&#xff0c;我们可以把起床的闹钟提前 30 分钟&#xff0c;比如原来 07:30 的闹钟可以改为 07:00。不用担心提前 30 分钟起床会影响休息质量&#xff0c;习惯以后&#xff0c;早起 30 分钟不但不会影响一天的精力&#xff0c;甚至可能反而让人更有精神。早起…

BUG:AttributeError: module ‘numpy‘ has no attribute ‘bool‘.

BUG:AttributeError: module ‘numpy’ has no attribute ‘bool’. 环境 Linux numpy 1.26.3详情 使用NumPy库时遇到&#xff1a;AttributeError: module numpy has no attribute bool报错。 错误原因 目前最新的的NumPy版本&#xff08;如1.26版本&#xff09;中布尔类型…

SAP ScreenPersonas

https://developers.sap.com/mission.screen-personas.html 跟着这个练习做一遍就了解了Personas 访问SAP提供的Personas练习系统 申请用户 登录练习系统 随便找一个可以支持Personas的程序搞起来&#xff0c;比如IW51 执行后等它出现这个图标就可以开始了.

js中的window和Window

示例&#xff1a; window.name name; console.log(window.name) // name console.log(Window.name) // Window由此可见Window和window是有区别的。 console.log(Object.prototype.toString.call(Window)); // [object Function] console.log(Object.prototype.toString.c…