当前位置: 首页 > news >正文

Linux多进程和多线程(七)进程间通信-信号量

进程间通信之信号量

资源竞争

多个进程竞争同一资源时,会发生资源竞争。
资源竞争会导致进程的执行出现不可预测的结果。

临界资源

不允许同时有多个进程访问的资源, 包括硬件资源 (CPU、内存、存储器以及其他外
围设备) 与软件资源(共享代码段、共享数据结构)

临界区

多个进程共享的资源被称为临界资源,
这些资源被保护在一个临界区中,
只有进入临界区的进程才能访问临界资源。

信号量

信号量是一种进程间通信机制,用于协调对共享资源的访问。

多进程对stdout资源的竞争

//多进程对stdout资源的竞争#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>int main(){pid_t cpid;cpid = fork();//创建子进程if(cpid < 0){printf("fork error\n");//fork失败exit(EXIT_FAILURE);//EXIT_FAILURE表示程序运行失败} else if(cpid == 0){//子进程while(1){printf("------------------------\n");printf("C Start.\n");sleep(1);printf("C End.\n");printf("------------------------\n");}} else{//父进程while(1){printf("------------------------\n");printf("P Start.\n");sleep(1);printf("P End.\n");printf("------------------------\n");}wait(NULL); //等待子进程结束}return 0;
}

代码的输出混乱:

------------------------
P Start.
------------------------
C Start.
P End.
------------------------
C End.
------------------------
------------------------
P Start.
------------------------
C Start.
P End.
C End.
------------------------
------------------------

同步和互斥

互斥

互斥是指进程独占资源,使得其他进程无法访问该资源。

同步

同步是指进程间通信,用于协调进程的执行。
同步在互斥的基础上增加了进程对临界资源的访问顺序
进程主要的同步与互斥手段是信号量

信号量

信号量,由内核维护的整数,其值被限制为大于或等于0;
信号可以执行一下操作:

  • 将信号量设置成一个具体的值;
  • 在信号量当前的基础上加上一个数值;
  • 在信号量当前值的基础上减上一个数值;
  • 等待信号量的值为0;

一般信号量分为

  • 二值信号量:一般指的是信号量值为1,可以理解为只对应一个资源
  • 计数信号量:一般指的是值大于等于2,可以理解为对应多个资源

在linux系统中使用ipcs -s 查询系统中信号量

创建信号量集合

调用 semget() 函数

函数头文件:

#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/types.h>int semget(key_t key, int nsems, int semflg);

函数功能:创建一个信号量集合;

函数参数:

  • key: 信号量集合的键值, 用于标识信号量集合;由ftok()函数生成;
  • nsems: 信号量集合中信号量的个数;
  • semflg: 信号量集合的标志位, 用于设置信号量集合的属性;
    • IPC_CREAT: 如果key对应的信号量集合不存在, 则创建新的信号量集合;
    • IPC_EXCL: 如果key对应的信号量集合已经存在, 则返回-1;
    • 权限标志

函数返回值:

  • 成功: 返回信号量集合的ID;
  • 失败: 返回-1, 并设置errno;
//多进程对stdout资源的竞争#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/sem.h>#define MSG_PATH "/home/gopher"
#define MSG_ID 88
int main(){key_t key;//通过文件路径和ID生成key,key= ftok(MSG_PATH,MSG_ID);if(key==-1){printf("ftok()");exit(EXIT_FAILURE);}//创建信号量集合,包含了一个信号量,编号为0int semid=semget(key,1,IPC_CREAT|0666);if(semid==-1){printf("semget()");exit(EXIT_FAILURE);}return 0;
}

创建出一个信号量集合,包含了一个信号量,编号为0

在这里插入图片描述

初始化信号量

调用 semctl() 函数

函数头文件:

#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/types.h>int semctl(int semid, int semnum, int cmd, ... /* arg */ );

函数功能:对信号量集合中的信号量进行操作;根据cmd 决定当前函数的功能;

函数参数:

  • semid: 信号量集合的ID;
  • semnum: 信号量的编号;编号从0开始;
  • cmd: 信号量操作命令;
    • SETVAL:设置信号量的值。
    • GETPID:返回最后一个执行 semop 操作的进程的PID。
    • GETVAL:返回指定信号量的值。
    • GETALL:返回信号量集中所有信号量的值。
    • GETNCNT:返回正在等待信号量增加的进程数。
    • GETZCNT:返回正在等待信号量变为零的进程数。
    • SETALL:设置信号量集中所有信号量的值。
    • IPC_STAT:获取信号量集的状态信息。
    • IPC_SET:设置信号量集的状态信息。
    • IPC_RMID:删除信号量集。
  • … :是属于可变参参数列表,根据不同的命令有不同的参数;

函数返回值:

  • 成功: 根据不同的cmd, 返回不同的结果;

  • GETPID:返回等待最后一个 semop 操作的进程的 PID。

    GETVAL:返回指定信号量的值。
    ls
    GETALL:如果成功,返回 0。

    GETNCNT:返回正在等待增加信号量值的进程数量。

    GETZCNT:返回正在等待信号量值为零的进程数量。

    IPC_STAT:如果成功,返回 0。

    IPC_SET:如果成功,返回 0。

    IPC_RMID:如果成功,返回 0。

    SETVAL:如果成功,返回 0。

    SETALL:如果成功,返回 0。

  • 失败: 返回-1, 并设置errno;

//多进程对stdout资源的竞争#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/sem.h>#define MSG_PATH "/home/gopher"
#define MSG_ID 88union semun{int val;
};
int main(){key_t key;//通过文件路径和ID生成key,key= ftok(MSG_PATH,MSG_ID);if(key==-1){printf("ftok()");exit(EXIT_FAILURE);}//创建信号量集合,包含了一个信号量,编号为0int semid=semget(key,1,IPC_CREAT|0666);if(semid==-1){printf("semget()");exit(EXIT_FAILURE);}union semun s;//定义一个联合体,用于设置信号量的值s.val=1;//设置信号量的值为1int ret=semctl(semid,0,SETVAL,s);//设置semid信号集中的第编号为0的信号量的值为1if(ret==-1){printf("semctl()");exit(EXIT_FAILURE);}return 0;
}

信号量操作

  • 信号量可以进⾏以下操作:
    • 对信号量的值加 1
    • 对信号量的值减 1
    • 等待信号量的值为 0

调用 semop() 函数

函数头文件:

#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/types.h>int semop(int semid, struct sembuf *sops, size_t nsops);

函数功能:对信号量集合中的信号量进行操作;

函数参数:

  • semid: 信号量集合的ID;
  • sops: 信号量操作结构体指针
  • nsops: 信号量操作结构体的个数;

函数返回值:

  • 成功: 返回 0;
  • 失败: 返回-1, 并设置errno;

struct sembuf *sops: 信号量操作结构体指针

struct sembuf
{unsigned short int sem_num;//信号量编号,从0开始short int sem_op;	        //信号量操作//-1:占用资源// +1:释放资源// 0:等待资源short int sem_flg;		//信号量操作标志位//IPC_NOWAIT:非阻塞,在信号量的值为0时,立即返回// SEM_UNDO:在进程终止时,会自动释放信号量
};

信号量集合删除

调用 semctl() 函数 ,设置命令为 IPC_RMID

在使用 semctl() 函数删除信号量集合时,需要注意第三个参数会被忽略

信号量互斥应用

使用信号量实现进程间互斥,同一时间只有一个进程访问临界资源

1.创建sem.h

#ifndef _mySEM_H_
#define _mySEM_H_
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>//创建信号量集
int sem_create(int names,unsigned short value[]);
//占用信号量
int sem_p(int semid,int semnum);
//释放信号量
int sem_v(int semid,int semnum);
//删除信号量集
int sem_delete(int semid);#endif /* _SEM_H_ */

2.创建sem.c

#include "sem.h"union semun {int              val;    /* Value for SETVAL */struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */unsigned short  *array;  /* Array for GETALL, SETALL */struct seminfo  *__buf;  /* Buffer for IPC_INFO(Linux-specific) */};//创建信号量集
//@param names 信号量集的个数
//@param value 信号量集的初始值
//@return 成功返回信号量集的id,失败返回-1
int sem_create(int names,unsigned short value[]){key_t key;//创建keykey= ftok(".",88);if (key == -1){perror("ftok");return -1;}//创建信号量集int semid;semid = semget(key,names,IPC_CREAT|0666);//参数:key,信号量集的个数,权限if (semid == -1){perror("semget");return -1;}union semun s; //定义union semuns.array = value;//将value数组赋值给union semun的array成员//初始化信号量集int ret=semctl(semid,0,SETALL,s);//这个操作将value数组中的值设置到信号量集中if (ret == -1){perror("semctl");return -1;}return semid;}//占用信号量
//@param semid 信号量集的id
//@param semnum 信号量的编号
int sem_p(int semid,int semnum){struct sembuf sem_b;//定义一个信号量操作结构体sem_b.sem_num=semnum;//信号量编号sem_b.sem_op= -1;//占用资源sem_b.sem_flg=SEM_UNDO;//在进程终止时,会自动释放信号量//操作1个信号量,如果操作多个信号量,需要创建sembuf结构体的数组int r= semop(semid,&sem_b,1); //失败返回-1,并设置errno   return r;
}
//释放信号量
int sem_v(int semid,int semnum){struct sembuf sem_b;//定义一个信号量操作结构体sem_b.sem_num=semnum;//信号量编号sem_b.sem_op= 1;//释放资源sem_b.sem_flg=SEM_UNDO;//在进程终止时,会自动释放信号量int r= semop(semid,&sem_b,1); //操作1个信号量,如果操作多个信号量,需要创建sembuf结构体的数组//失败返回-1,并设置errno   return r;
}
//删除信号量集
int sem_delete(int semid){int r= semctl(semid,0,IPC_RMID); //删除信号量集return r;
}

3.创建main.c

// 多进程对stdout资源的竞争#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include "sem.h"
int main()
{int semid;// 信号量IDunsigned short values[] = {1};// 信号量初始值semid = sem_create(1, values);if(semid == -1 ){printf("sem_create error\n");exit(EXIT_FAILURE);}pid_t cpid;// 子进程IDcpid = fork(); // 创建子进程if (cpid < 0){printf("fork error\n"); // fork失败exit(EXIT_FAILURE);     // EXIT_FAILURE表示程序运行失败}else if (cpid == 0){ // 子进程while (1){sem_p(semid,0);printf("------------------------\n");printf("C Start.\n");sleep(1);printf("C End.\n");printf("------------------------\n");sem_v(semid,0);}}else{ // 父进程while (1){sem_p(semid,0);printf("------------------------\n");printf("P Start.\n");sleep(1);printf("P End.\n");printf("------------------------\n");sem_v(semid,0);}wait(NULL); // 等待子进程结束}return 0;
}

4.编译运行


------------------------
P Start.
P End.
------------------------
------------------------
C Start.
C End.
------------------------
------------------------
P Start.
P End.
------------------------
------------------------
C Start.
C End.
----------

信号量同步应用

同步在互斥的基础上增加了进程对临界资源的访问顺序
进程主要的同步与互斥手段是信号量

示例:

创建⽗⼦进程,输出 “ABA” 字符串,具体需求如下:
⽗进程 输出 A
⼦进程 输出 B
⽗进程 输出 A ,输出换⾏
能够循环输出 “ABA” 字符

基本思路:

通过创建⼀个信号量集合,包含 2 个信号量,⼀个信号量 编号为 0
(SEM_CONTROL_P)控制⽗进程的运⾏与暂停,⼀个信号量 编号为 1
(SEM_CONTROL_C) 控制⼦进程的运⾏与暂停

// 多进程对stdout资源的竞争#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include "sem.h"#define SEM_C = 1
#define SEM_P = 0
// todo 创建一个信号量集合,集合中两个信号量,信号量0的值是1,信号量1的值是0;
int main()
{int semid;                         // 信号量IDunsigned short values[2] = {1, 0}; // 信号量初始值// todo 创建一个信号量集合,集合中两个信号量,信号量编号0的值是1,信号量编号1的值是0;semid = sem_create(2, values);if (semid == -1){printf("sem_create error\n");exit(EXIT_FAILURE);}pid_t cpid; // 子进程IDcpid = fork(); // 创建子进程if (cpid < 0){printf("fork error\n"); // fork失败exit(EXIT_FAILURE);     // EXIT_FAILURE表示程序运行失败}else if (cpid == 0){ // 子进程while (1){sem_p(semid, 1); //?占用信号量编号1,信号量编号1的值初始是0 ,在这里阻塞,等待父进程操作printf("B");fflush(stdout); // 刷新缓冲sem_v(semid, 0); //!释放信号量编号0,信号量编号0的值 0=>1,此时父进程不再阻塞,第二次占用0}}else{ // 父进程while (1){//@param semid 信号量集的id//@param semnum 信号量的编号sem_p(semid, 0); //?占用信号量编号0,信号量编号0的值 1=>0printf("A");fflush(stdout);  // 刷新缓冲sem_v(semid, 1); //?释放信号量编号1,信号量编号1的值 0=>1,此时子进程不再阻塞sem_p(semid, 0); //!第二次占用信号量编号0,信号量编号0的值是0,在这里阻塞,等待子进程的操作printf("A\n");fflush(stdout);  // 刷新缓冲sem_v(semid, 0);sleep(1);}wait(NULL); // 等待子进程结束}return 0;
}
0的值 0=>1,此时父进程不再阻塞,第二次占用0}}else{ // 父进程while (1){//@param semid 信号量集的id//@param semnum 信号量的编号sem_p(semid, 0); //?占用信号量编号0,信号量编号0的值 1=>0printf("A");fflush(stdout);  // 刷新缓冲sem_v(semid, 1); //?释放信号量编号1,信号量编号1的值 0=>1,此时子进程不再阻塞sem_p(semid, 0); //!第二次占用信号量编号0,信号量编号0的值是0,在这里阻塞,等待子进程的操作printf("A\n");fflush(stdout);  // 刷新缓冲sem_v(semid, 0);sleep(1);}wait(NULL); // 等待子进程结束}return 0;
}

相关文章:

Linux多进程和多线程(七)进程间通信-信号量

进程间通信之信号量 资源竞争 多个进程竞争同一资源时&#xff0c;会发生资源竞争。 资源竞争会导致进程的执行出现不可预测的结果。 临界资源 不允许同时有多个进程访问的资源, 包括硬件资源 (CPU、内存、存储器以及其他外 围设备) 与软件资源(共享代码段、共享数据结构) …...

【项目日记(一)】梦幻笔耕-数据层实现

❣博主主页: 33的博客❣ ▶️文章专栏分类:项目日记◀️ &#x1f69a;我的代码仓库: 33的代码仓库&#x1f69a; &#x1faf5;&#x1faf5;&#x1faf5;关注我带你了解更多项目内容 目录 1.前言2.后端模块3数据库设计4.mapper实现4.1UserInfoMapper4.2BlogMapper 5.总结 1.…...

ElementUI的中国省市区级联数据插件element-china-area-data

安装 npm install element-china-area-data -S import 使用 import {provinceAndCityData,pcTextArr,regionData,pcaTextArr,codeToText, } from "element-china-area-data"; provinceAndCityData省市二级联动数据,汉字+coderegionData省市区三级联动数据pcTextAr…...

Kotlin算法:把一个整数向上取值为最接近的2的幂指数值

Kotlin算法&#xff1a;把一个整数向上取值为最接近的2的幂指数值 import kotlin.math.ln import kotlin.math.powfun main(args: Array<String>) {val number intArrayOf(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18)number.forEach {println("$…...

简单且循序渐进地查找软件中Bug的实用方法

“Bug”这个词常常让许多开发者感到头疼。即使是经验丰富、技术娴熟的开发人员在开发过程中也难以避免遭遇到 Bug。 软件中的故障会让程序员感到挫败。我相信在你的软件开发生涯中&#xff0c;也曾遇到过一些难以排查的问题。软件中的错误可能会导致项目无法按时交付。因此&…...

基于springboot+vue+uniapp的高校宿舍信息管理系统小程序

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…...

(完整音频)DockerHub、OpenAI、GitCode,脱钩时代,我们该如何自处?

本期主播 朱峰&#xff1a;「津津乐道播客网络」创始人&#xff0c;产品及技术专家。&#xff08;微博&#xff1a;zhufengme&#xff09;高春辉&#xff1a;「科技乱炖」主播。“中国互联网站长第一人”&#xff0c;科技、互联网领域的连续创业者。&#xff08;微博&#xff1…...

macos 10.15系统下载包,macOS Catalina for mac

macOS Catalina 让你喜欢的种种 Mac 体验都更进一步。你可以领略音乐、播客这两款全新 Mac app 的表演&#xff1b;在 Mac 上畅享各款自己心爱的 iPad app&#xff1b;拿起 iPad 和 Apple Pencil&#xff0c;拓展工作空间&#xff0c;释放创意灵感&#xff1b;再打开那些平时常…...

uni.showShareMenu({}) 和 uni.showShareImageMenu({}) 的区别

ChatGPT uni.showShareMenu({}) 和 uni.showShareImageMenu({}) 是 Uni-app 中两个不同的 API&#xff0c;它们的作用和用法有所不同&#xff1a; uni.showShareMenu({}) 作用&#xff1a;用于显示当前页面的分享菜单&#xff0c;通常显示在页面的右上角&#xff08;类似于微…...

Spring Boot logback 日志文件配置

引入依赖 <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version></dependency>logback-spring.xml 配置 <?xml version"1.0" encoding"UTF-8&quo…...

240705_昇思学习打卡-Day17-基于 MindSpore 实现 BERT 对话情绪识别

240705_昇思学习打卡-Day17-基于 MindSpore 实现 BERT对话情绪识别 近期确实太忙&#xff0c;此处仅作简单记录&#xff1a; 模型简介 BERT全称是来自变换器的双向编码器表征量&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;&#xff0c…...

图像处理调试软件推荐

对于图像处理的调试&#xff0c;使用具有图形用户界面&#xff08;GUI&#xff09;且支持实时调整和预览的图像处理软件&#xff0c;可以大大提高工作效率。以下是几款常用且功能强大的图像处理调试软件推荐&#xff1a; ImageJ/FijiMATLABOpenCV with GUI LibrariesNI Vision …...

Mybatis实现RBAC权限模型查询

RBAC权限模型 Role-Based Access Control&#xff0c;中文意思是&#xff1a;基于角色&#xff08;Role&#xff09;的访问控制。这是一种广泛应用于计算机系统和网络安全领域的访问控制模型。 简单来说&#xff0c;就是通过将权限分配给➡角色&#xff0c;再将角色分配给➡用…...

最短路算法——差分约束

差分约束 (1) 求不等式组的可行解 源点&#xff1a;从源点出发&#xff0c;一定可以走到所有的边求可行解步骤&#xff1a; 先将每个不等式 x i ≤ x j c x_i \le x_j c xi​≤xj​c,转化成一条从 s j s_j sj​走到 s i s_i si​&#xff0c;长度为 c k c_k ck​ 的一条边找…...

Log4j日志框架讲解(全面,详细)

目录 Log4j概述 log4j的架构&#xff08;组成&#xff09; Loggers Appenders Layouts 快速入门 依赖 java代码 日志的级别 log4j.properties 自定义Logger 总结&#xff1a; Log4j概述 Log4j是Apache下的一款开源的日志框架&#xff0c;通过在项目中使用 Log4J&…...

LeetCode 35, 242, 994

目录 35. 搜索插入位置题目链接标签思路代码 242. 有效的字母异位词题目链接标签思路代码 994. 腐烂的橘子题目链接标签思路代码 35. 搜索插入位置 题目链接 35. 搜索插入位置 标签 数组 二分查找 思路 本题与 704. 二分查找 十分相似&#xff0c;只不过本题在找不到 tar…...

ctfshow-web入门-文件包含(web87)巧用 php://filter 流绕过死亡函数的三种方法

目录 方法1&#xff1a;php://filter 流的 base64-decode 方法 方法2&#xff1a;通过 rot13 编码实现绕过 方法3&#xff1a;通过 strip_tags 函数去除 XML 标签 除了替换&#xff0c;新增 file_put_contents 函数&#xff0c;将会往 $file 里写入 <?php die(大佬别秀了…...

adb shell ps -T打印出来参数的含义,以及D,T,Z代表的状态含义是什么?

在Android系统中&#xff0c;使用adb shell ps命令可以查看当前系统中运行的进程信息。当你添加-T选项时&#xff08;注意&#xff0c;标准的ps命令在Android的adb shell中可能不直接支持-T选项&#xff0c;这通常与Linux中的ps命令略有不同&#xff09;&#xff0c;你可能是想…...

leetcode77组合——经典回溯算法

本文主要讲解组合的要点与细节&#xff0c;以及回溯算法的解题步骤&#xff0c;按照步骤思考更方便理解 c和java代码如下&#xff0c;末尾 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 具体要点&#xff1a; …...

springcloud-alibba之FeignClient

代码地址&#xff1a;springcloud系列: springcloud 组件分析拆解 1.FeignClient的集成 springboot版本&#xff1a;3.1.5 springcloud组件版本&#xff1a;2022.0.4 nacos客户端的版本&#xff1a;2.3.2 1.引pom 这里引入了nacos和feginclient的版本 <dependency>…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...

华为OD机试-最短木板长度-二分法(A卷,100分)

此题是一个最大化最小值的典型例题&#xff0c; 因为搜索范围是有界的&#xff0c;上界最大木板长度补充的全部木料长度&#xff0c;下界最小木板长度&#xff1b; 即left0,right10^6; 我们可以设置一个候选值x(mid)&#xff0c;将木板的长度全部都补充到x&#xff0c;如果成功…...

【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error

在前端开发中&#xff0c;JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作&#xff08;如 Promise、async/await 等&#xff09;&#xff0c;开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝&#xff08;r…...