进程IO之 进程

一、进程相关概念

1.什么是进程

程序:静态的,编译好的可执行文件,存放在磁盘中的指令和数据的集合

进程:动态的,是程序的一次执行过程,是独立的可调度的任务

2.进程的特点

(1)对32位系统,系统会为每个进程分配0~4G的虚拟空间,其中,0~3G(用户空间)是每个进程独有的,3~4G(内核空间)是所有进程共有

      进程间通信:通过内核空间

(2)  CPU调度进程时会给进程分配时间片(几毫秒~十几毫秒),当时间片用完后,cpu再进行其他进程的调度,实现进程的轮转,从而实现多任务的操作。(没有外界干预的情况下怎么调度进程是CPU随机分配的 )

(3)进程控制块task_struct(了解)

● 进程控制块pcb:包含描述进程的相关信息

● 进程标识PID:唯一的标识一个进程

                主要进程标识:

                进程号(PID: Process Identity Number)

                父进程号:(Parent Process ID: PPID)

● 进程用户

● 进程状态、优先级

● 文件描述符(记录当前进程打开的文件)

3.进程段

Linux中的进程大致包含三个段:

数据段存放的是全局变量、常数以及动态数据分配的数据空间(如malloc函数取得的空间)等。

正文段:存放的是程序中的代码

堆栈段存放的是函数的返回地址、函数的参数以及程序中的局部变量 (类比内存的栈区)

4.进程分类

 交互进程:该类进程是由shell控制和运行的。交互进程既可以在前台运行,也可以在后台运行。 该类进程经常与用户进行交互,需要等待用户的输入,当接收到用户的输入后,该类 进程会立刻响应,典型的交互式进程有:shell命令进程、文本编辑器等

批处理进程:该类进程不属于某个终端,它被提交到一个队列中以便顺序执行。

守护进程:该类进程在后台运行。它一般在Linux启动时开始执行,系统关闭时才结束。
               (使用top命令查看进程信息时,tty字段为?的进程)

 5.进程状态

                      

6. 进程状态切换

           

 7.进程相关命令

 补充:根据进程的优先级进行调度,优先级高的进程先执行。

两种类型:

1.  非剥夺式(非抢占式)优先级调度算法。当一个进程正在处理上运行时,即使有某个更为重要或紧迫的进程进入就绪队列,仍然让正在进行的进程继续运行,直到由于其自身原因而主动让出处理机(任务完成或等待事件),才把处理机分配给更为重要或紧迫的进程。

2.  剥夺式(抢占式)优先级调度算法。当一个进程正在处理机上运行时,若有某个更为重要或紧迫的进程进入就绪队列,则立即暂停正在运行的进程,将处理机分配给更重要或紧迫的进程。

二、进程函数接口

1.创建进程 fork()

 #include <sys/types.h>#include <unistd.h>/*
功能:创建子进程参数:无返回值:   成功:父进程-->返回子进程进程号子进程-->返回0失败:父进程-->返回-1,并设置errno子进程并未创建*/
pid_t fork(void);

fork函数特点:

1)子进程几乎拷贝了父进程的全部内容。包括代码、数据、系统数据段中的pc值、栈中的数据、父进程中打开的文件等;但它们的PID、PPID是不同的。

2)父子进程有独立的地址空间,互不影响;当在相应的进程中改变全局变量、静态变量,都互不影响。

3)若父进程先结束,子进程成为孤儿进程,被init进程收养,子进程变成后台进程。

4)若子进程先结束,父进程如果没有及时回收资源,子进程变成僵尸进程(要避免僵尸进程产生)

2.回收资源wait()

 #include <sys/types.h>#include <sys/wait.h>/*
功能:回收进程资源(是一个阻塞函数)参数:子进程的退出状态,不接受子进程状态的话就将参数设为NULL返回值:成功 ---> 返回子进程的进程号失败--->返回-1*/pid_t wait(int *wstatus);
#include <sys/types.h>
#include <sys/wait.h>/*
功能:回收进程资源(是一个阻塞函数)参数: pid:>0  指定某一个子进程=-1 任意子进程=0  等待其组ID等于调用进程的组ID的任一子进程<-1  等待其组ID等于pid的绝对值的任一子进程status:子进程退出状态options:0 阻塞  WNOHANG 非阻塞返回值: 成功:当options的值设置成 0时:返回结束的子进程的进程号当options的值设置成WNOHANG时若此时子进程已经结束,返回结束的子进程的进程号若此时子进程已经结束,返回 0失败:返回-1*/pid_t waitpid(pid_t pid, int *wstatus, int options);

wait(NULL)   <==>  wait(-1,NULL,0)

3.结束进程exit()


参数:status是一个整型的参数,可以利用这个参数传递进程结束时的状态。通常0表示正常结束;
其他的数值表示出现了错误,进程非正常结束#include <stdlib.h>
void exit(int status);
功能:结束进程,刷新缓存#include <unistd.h>
void _exit(int status);
功能:结束进程,不刷新缓存

 常用:exit(0)

4.获取进程号getpid()

 #include <sys/types.h>#include <unistd.h>pid_t getpid(void);
功能:获取当前进程的进程号
pid_t getppid(void);
功能:获取当前进程的父进程号

在父进程中获取子进程的PID  :通过fork()的返回值 

        

三、进程间通信 (IPC)

 1.通信方式介绍:

  • 早期的进程间通信:无名管道(pipe) 有名管道(fifo)信号(signal)
  • system V IPC:   共享内存 (share memory) 消息队列(message queue) 信号集(semaphore set)
  • BSD: 套接字(socket)

2.无名管道

                    

特点:

(1)  只能用于具有亲缘关系的进程之间的通信

(2)  半双工的通信模式,具有固定的读端fd[0]和写端fd[1]。

(3)  无名管道可以看成是一种特殊的文件(实际是找不到这个文件的),对于它的读写可以使用文件IO如read、write函数进行操作。

(4)  管道是基于文件描述符的通信方式。当一个管道建立时,它会创建两个文件描述符 fd[0]和fd[1]。其中fd[0]固定用于读管道,而fd[1]固定用于写管道。

函数接口: 

int pipe(int fd[2])
功能:创建无名管道
参数:文件描述符 fd[0]:读端  fd[1]:写端
返回值:成功 0失败 -1

3.有名管道

特点:

1)  有名管道可以使互不相关的两个进程互相通信。

2)  有名管道可以通过路径名来指出,并且在文件系统中可见,但内容存放在内存中。但是读写数据不会存在文件中,而是在管道中,也就是内核空间中

3)  进程通过文件IO来操作有名管道

4)  不支持如lseek() 操作

5)  有名管道遵循先进先出规则

 函数接口:

/*
功能:创健有名管道
参数:filename:有名管道文件名mode:权限
返回值:成功:0失败:-1,并设置errno号*/int mkfifo(const char *filename,mode_t mode);

4.信号

 kill -l  :查看系统中的信号

kill -num PID :给某个进程发信号

4.1概念:

  • 信号是软件层面上对中断机制的一种模拟,是一种异步通信模式。
  • 信号可以直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间进程发生了哪些系统事件。
  • 如果该进程当前并未处于执行态,则该信号就由内核保存起来,直到该进程恢复执行再传递给它;如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被取消时才被传递给进程。

4.2信号的响应方式

  • 忽略信号 :对信号不做任何处理,但是有两个信号不能忽略:即SIGKILL及SIGSTOP。
  • 捕捉信号:定义信号处理函数,当信号发生时,执行相应的处理函数
  • 执行缺省操作:Linux对每种信号都规定了默认操作

4.3信号种类

4.4函数接口

 (1)信号的发送kill()和挂起 pause()
#include <sys/types.h>
#include <signal.h>
/*
功能:信号发送
参数:pid:指定进程sig:要发送的信号
返回值:成功 0     失败 -1*/int kill(pid_t pid, int sig);
#include <signal.h>
/*
功能:进程向自己发送信号
参数:sig:信号
返回值:成功 0   失败 -1*/int raise(int sig);

       注意:     raise( sig )  <==> kill ( getpid() , sig )

#include <unistd.h>/*功能:用于将调用进程挂起(类似于死循环且不占用CPU资源),直到收到被捕获处理的信号为止。*/
int pause(void);

 注意:若程序中有使用signal的捕捉信号自定义函数处理时,pause接收到被捕获处理的信号以后会结束挂起

 (2)定时器alarm()
 #include <unistd.h>/*
功能:在进程中设置一个定时器。当定时器指定的时间到了时,它就向进程发送SIGALARM信号。
参数:seconds:定时时间,单位为秒
返回值:如果调用此alarm()前,进程中已经设置了闹钟时间,则返回上一个闹钟时间的剩余时间,否则返回0。*/
unsigned int alarm(unsigned int seconds);

注意:

1)一个进程只能有一个闹钟时间。如果在调用alarm时已设置过闹钟时间,则之前的闹钟时间被新值所代替。

2)系统默认对SIGALRM(闹钟到点后内核发送的信号)信号的响应: 如果不对SIGALRM信号进行捕捉或采取措施,默认情况下,闹钟响铃时刻会退出进程(程序非正常结束,要注意刷新问题!!)。

3)常用操作:取消定时器alarm(0),返回旧闹钟余下秒数。

4)alarm是非阻塞函数

 (3)信号处理函数signal()
 #include <signal.h>/*
功能:信号处理函数参数:signum:要处理的信号handler:信号处理方式忽略信号 (SIG_IGN)执行默认操作 (SIG_DFL)捕捉信号并执行自定义操作 (自定义函数名)返回值:成功:设置之前的信号处理方式失败:-1*/sighandler_t signal(int signum, sighandler_t handler);

补充:

sighandler_t  是一个 函数指针 的重命名 (该指针指向的函数是一个 无返回值,形参为一个整型的类型函数

 typedef void (*sighandler_t)(int);  

5. 共享内存

5.1特点

1)共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝。

2)为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程

将其映射到自己的私有地址空间。进程就可以直接读写这一内存区而不需要进行数据的拷贝,从而大大提高的效率。

3)  由于多个进程共享一段内存,因此也需要依靠某种同步机制,如互斥锁和信号量等

 

5.2步骤

(1)  创建key

(2)  创建打开共享内存

(3)  映射共享内存到用户空间

(4)  撤销映射

(5)  删除共享内存

 5.3函数接口

(1)创建key值

使用pathname提供的文件的inode号和字符的ASCII码值通过某种计算方法得到key值

#include <sys/types.h>
#include <sys/ipc.h>
/*
功能:创建出来的具有唯一映射关系的一个key值,帮助操作系统用来标识一块共享内存
参数:Pathname:已经存在的可访问文件的名字Proj_id:一个字符(因为只用低8位,一个字符正好是8位)返回值:成功:key值失败:-1*/key_t ftok(const char *pathname, int proj_id);

(2)  创建打开共享内存

#include <sys/ipc.h>
#include <sys/shm.h>/*
功能:创建或打开共享内存
参数:key  键值size   共享内存的大小shmflg   IPC_CREAT|IPC_EXCL|0777
返回值:成功  返回共享内存号 shmid出错或共享内存已存在    -1*/int shmget(key_t key, size_t size, int shmflg);

 注意:shmget() 出错或共享内存已存在都返回 -1,因此,要在容错判断中在加一次判断,使用系统定义的file exist错误号进行判断

(3)  映射共享内存到用户空间

#include <sys/types.h>
#include <sys/shm.h>/*
功能:映射共享内存,即把指定的共享内存映射到进程的地址空间用于访问
参数:shmid   共享内存的id号shmaddr   一般为NULL,表示由系统自动完成映射如果不为NULL,那么有用户指定shmflg:SHM_RDONLY就是对该共享内存只进行读操作0     可读可写
返回值:成功:完成映射后的地址,出错:-1(地址)*/void  *shmat(int  shmid,const  void  *shmaddr,int  shmflg); 

最常使用形式:(强制转换)shmat(shmid,NULL,0);

容错判断:因为shmat()返回的是任意类型的指针,要注意强转

(4)  撤销映射

#include <sys/types.h>
#include <sys/shm.h>
/*
功能:取消映射
参数:要取消的地址
返回值:成功0  失败的-1*/int shmdt(const void *shmaddr);

(5)  删除共享内存

使用的是shmctl()函数的删除功能

#include <sys/ipc.h>
#include <sys/shm.h>
/*功能:(删除共享内存),对共享内存进行各种操作
参数:shmid   共享内存的id号cmd     IPC_STAT 获得shmid属性信息,存放在第三参数IPC_SET 设置shmid属性信息,要设置的属性放在第三参数IPC_RMID:删除共享内存,此时第三个参数为NULL即可buf    shmid所指向的共享内存的地址,空间被释放以后地址就赋值为null
返回:成功0 失败-1*/int  shmctl(int  shmid,int  cmd,struct shmid_ds *buf); 

即使用  shmctl(shmid,IPC_RMID,NULL);   

5.4 命令

ipcs -m  --->查看系统中的共享内存

ipcrm -m shmid  --->删除共享内存

注意:可能不能直接删除仍有进程使用的共享内存

(可通过ps -ef查看有哪些进程,kill掉相关进程后再执行操作)

6.信号灯集

6.1特点

信号灯(semaphore),也叫信号量,信号灯集是一个信号灯的集合。它是不同进程间或一个给定进程内部不同线程间同步的机制;

而Posix信号灯指的是单个计数信号灯:无名信号灯、有名信号灯。(咱们学的是无名信号灯)

System V的信号灯是一个或者多个信号灯的一个集合。其中的每一个都是单独的计数信号灯。

通过信号灯集实现共享内存的同步操作

6.2 步骤

(1)  创建key: ftok

(2)  创建打开信号灯集: semget

(3)  初始化信号灯: semctl

(4)  PV操作: semop

(5)  删除信号灯集: semctl

6.3 命令

ipcs -s

ipcrm -s

6.4 函数接口

int semget(key_t key, int nsems, int semflg);
功能:创建/打开信号灯
参数:key:ftok产生的key值nsems:信号灯集中包含的信号灯数目semflg:信号灯集的访问权限,通常为IPC_CREAT|IPC_EXCL|0666
返回值:成功:信号灯集ID失败:-1int semctl ( int semid, int semnum,  int cmd…/*union semun arg*/);
功能:信号灯集合的控制(初始化/删除)
参数:semid:信号灯集IDsemnum: 要操作的集合中的信号灯编号,信号灯编号从0开始cmd: GETVAL:获取信号灯的值,返回值是获得值SETVAL:设置信号灯的值,需要用到第四个参数:共用体IPC_RMID:从系统中删除信号灯集合
返回值:成功 0失败 -1
用法:
1. 初始化信号灯集:
需要自定义共用体
union semun{int val;
} mysemun;
mysemun.val = 10;
semctl(semid, 0, SETVAL, mysemun);2. 获取信号灯值:函数semctl(semid, 0, GETVAL)的返回值
3. 删除信号灯集:semctl(semid, 0, IPC_RMID);int semop ( int semid, struct sembuf  *opsptr,  size_t  nops);
功能:对信号灯集合中的信号量进行PV操作
参数:semid:信号灯集IDopsptr:操作方式nops:  要操作的信号灯的个数 1个
返回值:成功 :0失败:-1
struct sembuf {short  sem_num; // 要操作的信号灯的编号short  sem_op;  //    0 :  等待,直到信号灯的值变成0//   1  :  释放资源,V操作//   -1 :  申请资源,P操作                    short  sem_flg; // 0(阻塞),IPC_NOWAIT, SEM_UNDO
};用法:
申请资源 P操作:mysembuf.sem_num = 0;mysembuf.sem_op = -1;mysembuf.sem_flg = 0;semop(semid, &mysembuf, 1);
释放资源 V操作:mysembuf.sem_num = 0;mysembuf.sem_op = 1;mysembuf.sem_flg = 0;semop(semid, &mysembuf, 1);

7.消息队列

7.1特点

消息队列是IPC对象(活动在内核级别的一种进程间通信的工具)的一种

一个消息队列由一个标识符 (即队列号 --> msgid)来标识

消息队列就是一个消息的列表。用户可以在消息队列中添加消息、读取消息等

消息队列可以按照类型(自己设一个值作为类型)来发送/接收消息

7.2 步骤

(1)  创建key: ftok()

(2)  创建打开消息队列: msgget()

(3)  添加消息: 按照类型消息添加到已经打开的消息队列末尾msgsnd()

(4)  读取消息: 可以按照类型消息列表中取走 msgrcv()

(5)  删除消息队列msgctl()

7.3 操作命令

ipcs -q: 查看消息队列

ipcrm -q msgid: 删除消息队列

7.4 函数接口

(1)  创建key: ftok()   同前面的共享内存中的ftok函数

(2)  创建打开消息队列: msgget()

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>/*
功能:创建或打开一个消息队列
参数:  key值flag:创建消息队列的权限IPC_CREAT|IPC_EXCL|0666
返回值:成功:msgid失败:-1*/int msgget(key_t key, int flag);

注意:有时候可能会创建失败或者migid==0,因此创建完后都要用 ipcs -q 命令查看,若是则要用 ipcrm -q msgid 命令删除已建队列然后重新进行创建。

(3)  添加消息: 按照类型消息添加到已经打开的消息队列末尾msgsnd()

常用的消息结构:                                                         制作消息

                       

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>/*
功能:添加消息
参数:msqid:消息队列的IDmsgp:指向消息的指针。常用消息结构msgbuf如下:struct msgbuf{long mtype;          //消息类型char mtext[N]};     //消息正文size:发送的消息正文的字节数flag:IPC_NOWAIT消息没有发送完成函数也会立即返回    0:直到发送完成函数才返回 (阻塞等待)
返回值:成功:0失败:-1*/int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

(4)  读取消息: 可以按照类型消息列表中取走 msgrcv()

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>/*
功能:读取消息
参数:msgid:消息队列的IDmsgp:存放读取消息的空间size:接受的消息正文的字节数(sizeof(msgp)-sizeof(long))msgtype:0:接收消息队列中第一个消息。大于0:接收消息队列中第一个类型为msgtyp的消息.小于0:接收消息队列中类型值不小于msgtyp的绝对值且类型值又最小的消息。flag:0:若无消息函数会一直阻塞IPC_NOWAIT:若没有消息,进程会立即返回ENOMSG返回值:成功:接收到的消息的长度失败:-1*/ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);

(5)  删除消息队列msgctl()

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>/*
功能:对消息队列的操作,删除消息队列
参数:msqid:消息队列的队列IDcmd:IPC_STAT:读取消息队列的属性,并将其保存在buf指向的缓冲区中。IPC_SET:设置消息队列的属性。这个值取自buf参数。IPC_RMID:从系统中删除消息队列。buf:消息队列缓冲区
返回值:成功:0失败:-1
*/int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );
用法:msgctl(msgid, IPC_RMID, NULL

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

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

相关文章

Condition源码解读(二)

本章我们继续将Condition的最后一个方法signal方法&#xff0c;如果前面没有看过的可以点击LockSupport与Condition解析来看看Condition解读的前半部分。 signal方法&#xff1a; public final void signal() {if (!AbstractQueuedLongSynchronizer.this.isHeldExclusively())…

股票收益率的计算

首先&#xff0c;需要从 Tushare.pro 注册一个账号并调用其API获取股票日线数据&#xff08;具体操作请查看官网&#xff09;。 以通过调用tushare获取股票000001(平安银行)的股票数据为例&#xff0c;这里不设置日期&#xff0c;那么默认获取Tushare提供的所有历史数据。也可…

《算法笔记》13.2小节——专题扩展->树状数组(BIT) 问题 D: 数列-训练套题T10T3

数列(sequence.pas/c/cpp) - 问题描述 一个简单的数列问题&#xff1a;给定一个长度为n的数列&#xff0c;求这样的三个元素ai, aj, ak的个数&#xff0c;满足ai < aj > ak&#xff0c;且i < j < k。 - 输入数据 第一行是一个整数n(n < 50000)。 第二行n个整…

C# Windows Forms应用程序-001

目录 项目概述 主要组件及功能 类定义 控件声明 构造函数 Dispose 方法 InitializeComponents 方法 控件配置详解 Button 控件 (button1) TextBox 控件 (textBox1) GroupBox 控件 (groupBox1) Label 控件 (label1 至 label5) OpenFileDialog 控件 (openFileDialog1…

2025.5.28总结

今日工作&#xff1a;最近进入了项目的关键节点&#xff0c;要求每人每天提两单&#xff0c;今天周三&#xff0c;下班前只提了一个单。下午开了一场需求服务验收会&#xff0c;我演示了自己验收的那个需求&#xff0c;然后讲的不是很好。当初再构造数据时请教了一个人&#xf…

Transformer核心技术解析LCPO方法:精准控制推理长度的新突破

原创文章1FFN前馈网络与激活函数技术解析&#xff1a;Transformer模型中的关键模块2Transformer掩码技术全解析&#xff1a;分类、原理与应用场景3【大模型技术】Attention注意力机制详解一4Transformer模型中位置编码&#xff08;Positional Embedding&#xff09;技术全解析(…

在 WSL 中安装 JetBrains Toolbox:完整指南

JetBrains Toolbox 是一个非常实用的工具&#xff0c;它可以帮助开发者轻松管理 JetBrains 的各种开发工具&#xff0c;如 IntelliJ IDEA、PyCharm、WebStorm 等。通过它&#xff0c;你可以快速安装、更新和管理这些工具&#xff0c;极大地提高了开发效率。而在 WSL 环境中安装…

ZooKeeper 命令操作

文章目录 Zookeeper 数据模型Zookeeper 服务端常用命令Zookeeper 客户端常用命令 Zookeeper 数据模型 ZooKeeper 是一个树形目录服务,其数据模型和Unix的文件系统目录树很类似&#xff0c;拥有一个层次化结构。这里面的每一个节点都被称为&#xff1a; ZNode&#xff0c;每个节…

Turf.js:前端地理空间分析的瑞士军刀

在Web开发中,地理空间数据处理已成为许多应用的核心需求。从地图可视化到位置服务,再到复杂的数据分析,前端开发者需要强大的工具来处理这些任务。Turf.js 作为一款轻量级、模块化的地理空间分析库,凭借其丰富的功能和易用性,成为前端开发者的得力助手。本文将深入探讨 Tu…

大模型微调

使用 Ollama 微调大语言模型&#xff08;如 LLaMA、Mistral、Gemma 等&#xff09;主要是围绕 LoRA&#xff08;Low-Rank Adaptation&#xff09;或者 QLoRA 等轻量级微调技术进行的。Ollama 本身是一个部署和运行本地大语言模型的平台&#xff0c;但其微调能力有限&#xff0c…

《自动驾驶轨迹规划实战:Lattice Planner实现避障路径生成(附可运行Python代码)》—— 零基础实现基于离散优化的避障路径规划

《自动驾驶轨迹规划实战&#xff1a;Lattice Planner实现避障路径生成&#xff08;附可运行Python代码&#xff09;》 —— 零基础实现基于离散优化的避障路径规划 一、为什么Lattice Planner成为自动驾驶的核心算法&#xff1f; 在自动驾驶的路径规划领域&#xff0c;Lattice…

切换到旧提交,同时保证当前修改不丢失

在 Git 中&#xff0c;可以通过以下几种方式切换到之前的提交&#xff0c;同时保留当前的提交&#xff08;即不丢失工作进度&#xff09;&#xff1a; 1. 使用 git checkout 创建临时分离头指针&#xff08;推荐用于查看&#xff09; git checkout <commit-hash>这会让…

zookeeper 操作总结

zookeeper 中的节点类型 节点类型命令选项说明‌持久节点‌无选项&#xff08;默认&#xff09;永久存在&#xff0c;除非手动删除。‌临时节点‌-e与客户端会话绑定&#xff0c;会话结束自动删除&#xff08;‌不能有子节点‌&#xff09;。‌顺序节点‌-s节点名自动追加递增…

nova14 ultra,是如何防住80°C热水和10000KPa水压冲击的?

暴雨突袭&#xff0c;手忙脚乱护住背包&#xff0c;却担心手机被雨水浸湿&#xff1b;泳池里想记录美好时刻&#xff0c;却担心手机掉入水中 &#xff1b;厨房里充满了高温水汽&#xff0c;近距离拍摄美食瞬间&#xff0c;手机屏幕花屏&#xff0c;让人失去了对美食的兴趣…… …

flutter加载dll 报错问题

解决flutter加载dll 报错问题 LoadLibrary 报错 126 or 193 明确一点&#xff1a;flutter构建exe 时默认是MSVC的。 1. 先检查dll 的位数是否满足 file ***.dll output: PE32 executable (DLL) (console) x86-64, for MS Windows, 19 sections 这种是64位的机器。 满足的话可…

Mac 版不能连接华为 GaussDB 吗?我看 Windows 版可以连接?

&#x1f9d1;‍&#x1f4bb; GaussDB 用户 Mac 版不能连接华为 GaussDB 吗&#xff1f;我看Windows 版可以连接。 &#x1f9d1;‍&#x1f527; 官方技术中心 由于 GaussDB 数据库本身未支持 macOS 系统&#xff0c;所以在 macOS 上的 Navicat 中也未支持该数据库。 &…

【MySQL成神之路】MySQL索引相关介绍

1 相关理论介绍 一、索引基础概念 二、索引类型 1. 按数据结构分类 2. 按功能分类 三、索引数据结构原理 B树索引特点&#xff1a; 哈希索引特点&#xff1a; 四、索引使用原则 1. 创建索引原则 2. 避免索引失效情况 五、索引优化策略 六、索引维护与管理 七、特殊…

五、web安全--XSS漏洞(1)--XSS漏洞利用全过程

本文章仅供学习交流&#xff0c;如作他用所承受的法律责任一概与作者无关1、XSS漏洞利用全过程 1.1 寻找注入点&#xff1a;攻击者首先需要找到目标网站中可能存在XSS漏洞的注入点。这些注入点通常出现在用户输入能够直接输出到页面&#xff0c;且没有经过适当过滤或编码的地方…

使用 Shell 脚本实现 Spring Boot 项目自动化部署到 Docker(Ubuntu 服务器)

使用 Shell 脚本实现 Spring Boot 项目自动化部署到 Docker&#xff08;Ubuntu 服务器&#xff09; 在日常项目开发中&#xff0c;我们经常会将 Spring Boot 项目打包并部署到服务器上的 Docker 环境中。为了提升效率、减少重复操作&#xff0c;我们可以通过 Shell 脚本实现自动…

高考加油(Python+HTML)

前言 询问DeepSeek根据自己所学到的知识来生成多个可执行的代码&#xff0c;为高考学子加油。最开始生成的都会有点小问题&#xff0c;还是需要自己调试一遍&#xff0c;下面就是完整的代码&#xff0c;当然了最后几天也不会有多少人看&#xff0c;都在专心的备考。 Python励…