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

【Linux】进程间通信IPC机制

目录

一、无名管道

二、有名管道

三、共享内存

四、信号量

五、消息队列

六、套接字


一、无名管道

1.只能用于具有亲缘关系的进程之间的通信(也就是父子进程或者兄弟进程)。

2.是一个单工的通信模式,具有固定的读端和写端。

3.管道也可以看成是一种特殊的文件,对于它的读写也可以使用普通的read()、write()等函数。但是它不属于任何文件系统,并且只存在于内存中。

#include <unistd.h>
int pipe(int filedes[2]);
在管道中,文件描述符数组的第一个元素(索引为0)用于读取,第二个元素(索引为1)用于写入。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>#define BUFFER_SIZE 25
#define READ_END 0
#define WRITE_END 1int main() 
{char write_msg[BUFFER_SIZE] = "Hello, child!";char read_msg[BUFFER_SIZE];int fd[2];pid_t pid;// 创建管道if (pipe(fd) == -1) {fprintf(stderr, "Pipe failed");return 1;}// 创建子进程pid = fork();if (pid < 0) {fprintf(stderr, "Fork failed");return 1;}// 父进程if (pid > 0)   {// 关闭写入端,因为父进程不会写入close(fd[WRITE_END]);// 从管道中读取消息read(fd[READ_END], read_msg, BUFFER_SIZE);printf("Parent received message from child: %s\n", read_msg);// 关闭读取端close(fd[READ_END]);} // 子进程else {  // 关闭读取端,因为子进程不会读取close(fd[READ_END]);// 写入消息到管道write(fd[WRITE_END], write_msg, BUFFER_SIZE);// 关闭写入端close(fd[WRITE_END]);}return 0;
}

./a.out
执行结果:Parent received message from child: Hello, child! 

二、有名管道

  1. mkfifo(const char *pathname, mode_t mode):

    • 这个函数用于创建一个有名管道。
    • 参数pathname是要创建的管道的路径名,mode是指定管道权限的位掩码。
    • 返回值:成功时返回0,失败时返回-1,并设置errno变量表示错误类型。
  2. open(const char *pathname, int flags, mode_t mode):

    • 这个函数用于打开文件或管道。
    • 参数pathname是要打开的文件或管道的路径名,flags指定打开文件的方式(如只读、只写、读写等),mode是当创建新文件时指定的权限。
    • 返回值:成功时返回文件描述符,失败时返回-1,并设置errno变量表示错误类型。
  3. write(int fd, const void *buf, size_t count):

    • 这个函数用于向文件描述符指定的文件或管道中写入数据。
    • 参数fd是打开文件或管道时返回的文件描述符,buf是要写入的数据缓冲区,count是要写入的字节数。
    • 返回值:成功时返回实际写入的字节数,失败时返回-1,并设置errno变量表示错误类型。
  4. read(int fd, void *buf, size_t count):

    • 这个函数用于从文件描述符指定的文件或管道中读取数据。
    • 参数fd是打开文件或管道时返回的文件描述符,buf是用于接收数据的缓冲区,count是要读取的最大字节数。
    • 返回值:成功时返回实际读取的字节数,失败时返回-1,并设置errno变量表示错误类型。
  5. close(int fd):

    • 这个函数用于关闭打开的文件描述符。
    • 参数fd是要关闭的文件描述符。
    • 返回值:成功时返回0,失败时返回-1,并设置errno变量表示错误类型。
  6. unlink(const char *pathname):

    • 这个函数用于删除文件或链接。
    • 参数pathname是要删除的文件或链接的路径名。
    • 返回值:成功时返回0,失败时返回-1,并设置errno变量表示错误类型。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>#define BUFFER_SIZE 25int main() 
{char *fifo_name = "./name";char write_msg[BUFFER_SIZE] = "Hello, world!";char read_msg[BUFFER_SIZE];// 创建有名管道mkfifo(fifo_name, 0666);pid_t pid = fork();if (pid == 0)// 子进程负责写入{// 打开管道进行写入int fd_write = open(fifo_name, O_WRONLY);write(fd_write, write_msg, BUFFER_SIZE);close(fd_write);} else if (pid > 0) // 父进程负责读取{ // 打开管道进行读取int fd_read = open(fifo_name, O_RDONLY);read(fd_read, read_msg, BUFFER_SIZE);printf("Received message: %s\n", read_msg);close(fd_read);} else  // fork失败{fprintf(stderr, "Fork failed");return 1;}// 删除管道unlink(fifo_name);return 0;
}

三、共享内存

共享内存是最高效的,因为避免了数据在用户空间和内核空间的来回拷贝

  1. ftok(const char *pathname, int proj_id):

    • ftok()函数用于生成一个唯一的key,用于创建或访问共享内存。
    • 参数pathname是一个路径名,proj_id是一个整数,用于生成key。
    • 返回值:如果成功,返回一个唯一的key,如果失败,返回-1。
  2. shmget(key_t key, size_t size, int shmflg):

    • shmget()函数用于创建共享内存段或获取共享内存段的标识符。
    • 参数key是由ftok()生成的唯一key,size是共享内存的大小,shmflg是标志位,用于指定权限和行为。
    • 返回值:如果成功,返回共享内存段的标识符,如果失败,返回-1。
  3. shmat(int shmid, const void *shmaddr, int shmflg):

    • shmat()函数用于将共享内存连接到当前进程的地址空间。
    • 参数shmid是共享内存段的标识符,shmaddr通常为NULL(表示系统自动选择地址),shmflg是标志位,通常为0。
    • 返回值:如果成功,返回指向共享内存段的指针,如果失败,返回(void *)-1。
  4. shmdt(const void *shmaddr):

    • shmdt()函数用于将共享内存从当前进程的地址空间分离。
    • 参数shmaddr是指向共享内存段的指针。
    • 返回值:如果成功,返回0,如果失败,返回-1。
  5. shmctl(int shmid, int cmd, struct shmid_ds *buf):

    • shmctl()函数用于对共享内存进行控制操作,如删除共享内存段。
    • 参数shmid是共享内存段的标识符,cmd是控制命令,buf是一个指向shmid_ds结构体的指针,用于获取共享内存的状态信息。
    • 返回值:如果成功,返回0,如果失败,返回-1。

读端

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>#define SHM_SIZE 1024int main() 
{key_t key = ftok("/", 'R'); // 生成共享内存的key// 创建共享内存段int shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666);if (shmid == -1) {perror("shmget");exit(1);}// 将共享内存连接到当前进程的地址空间char *shmaddr = shmat(shmid, NULL, 0);if (shmaddr == (void *)-1) {perror("shmat");exit(1);}// 写入数据到共享内存strcpy(shmaddr, "Hello, shared memory!");// 分离共享内存if (shmdt(shmaddr) == -1) {perror("shmdt");exit(1);}printf("数据已写入共享内存\n");return 0;
}

 写端

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>#define SHM_SIZE 1024int main() 
{key_t key = ftok("/", 'R'); // 生成共享内存的key// 获取共享内存段int shmid = shmget(key, SHM_SIZE, 0666);if (shmid == -1) {perror("shmget");exit(1);}// 将共享内存连接到当前进程的地址空间char *shmaddr = shmat(shmid, NULL, 0);if (shmaddr == (void *)-1){perror("shmat");exit(1);}printf("从共享内存中读取到的消息:%s\n", shmaddr);// 分离共享内存if (shmdt(shmaddr) == -1) {perror("shmdt");exit(1);}return 0;
}

写端执行后:

数据已写入共享内存

读端执行后:

从共享内存中读取到的消息:Hello, shared memory! 

四、信号量

1.信号量实现互斥

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>#define KEY 1234 // 信号量的键值// 定义一个联合体,用于semctl初始化
union semun {int val;struct semid_ds *buf;unsigned short *array;
};// 创建一个二值信号量并初始化为1
int create_semaphore() 
{// 创建一个信号量集,包含1个信号量int semid = semget(KEY, 1, IPC_CREAT | 0666); if (semid == -1) {perror("semget");exit(1);
}union semun arg;arg.val = 1; // 初始值为1,表示资源可用if (semctl(semid, 0, SETVAL, arg) == -1) // 初始化信号量{perror("semctl");exit(1);}return semid;
}// P操作(等待资源)
void P(int semid) 
{struct sembuf op;op.sem_num = 0; // 信号量集中的第一个信号量op.sem_op = -1; // 对信号量执行P操作op.sem_flg = 0;if (semop(semid, &op, 1) == -1) {perror("semop");exit(1);}
}// V操作(释放资源)
void V(int semid) 
{struct sembuf op;op.sem_num = 0; // 信号量集中的第一个信号量op.sem_op = 1; // 对信号量执行V操作op.sem_flg = 0;if (semop(semid, &op, 1) == -1) {perror("semop");exit(1);}
}int main()
{int semid = create_semaphore(); // 创建信号量pid_t pid = fork(); // 创建子进程if (pid == -1) {perror("fork");exit(1);}if (pid == 0)  // 子进程{P(semid); // 等待资源printf("Child process: Counter decremented by 1.\n");V(semid); // 释放资源} else // 父进程{sleep(1); // 让子进程有机会先运行P(semid); // 等待资源printf("Parent process: Counter incremented by 1.\n");V(semid); // 释放资源}return 0;
}
  1. semget(key_t key, int nsems, int semflg)

    • 这个函数用于创建一个新的信号量集或获取一个现有信号量集的标识符。
    • key是一个用于唯一标识信号量集的键值。
    • nsems指定了信号量集中的信号量数量。
    • semflg是一组标志,用于指定创建信号量集的权限和行为。
    • 返回值:成功时返回信号量集的标识符,失败时返回-1。
  2. semctl(int semid, int semnum, int cmd, union semun arg)

    • 这个函数用于对信号量集进行控制操作,如初始化、设置值、获取值等。
    • semid是信号量集的标识符。
    • semnum是指定的信号量在集合中的索引,通常为0。
    • cmd是指定要执行的控制命令。
    • arg是一个联合体,用于传递控制命令的参数。
    • 返回值:根据控制命令不同而不同。
  3. semop(int semid, struct sembuf *sops, size_t nsops)

    • 这个函数用于执行一组信号量操作,如等待资源(P操作)和释放资源(V操作)。
    • semid是信号量集的标识符。
    • sops是一个指向信号量操作结构体数组的指针。
    • nsops是指定的信号量操作结构体数组的大小。
    • 返回值:成功时返回0,失败时返回-1。
  4. struct sembuf

    • 这是一个结构体,用于描述信号量操作。
    • 它包含了三个字段:
      • sem_num:信号量集中的信号量索引。
      • sem_op:信号量操作,通常是-1(P操作,等待资源)或1(V操作,释放资源)。
      • sem_flg:信号量操作的标志位,通常为0。
  5. union semun

    • 这是一个联合体,用于传递给semctl()函数的参数。
    • 它包含了多个字段,其中的一个字段可以根据不同的控制命令来使用,比如用于设置或获取信号量值时使用的val字段,用于获取信号量状态信息时使用的buf字段等

  1. create_semaphore():

    • 这个函数用于创建一个二值信号量,并将其初始化为1。
    • 首先,它调用 semget() 函数创建一个包含一个信号量的信号量集,如果创建失败则会打印错误信息并退出程序。
    • 然后,它使用 semctl() 函数将信号量的值初始化为1,表示资源可用。
    • 最后,它返回创建的信号量集的标识符。
  2. P(int semid):

    • 这个函数用于执行 P 操作,即等待资源。
    • 首先,它定义了一个 struct sembuf 结构体 op,用于描述信号量操作。
    • 然后,它将 op.sem_num 设置为0,表示信号量集中的第一个信号量。
    • 接着,它将 op.sem_op 设置为-1,表示对信号量执行 P 操作。
    • 最后,它调用 semop() 函数执行信号量操作,如果操作失败则会打印错误信息并退出程序。
  3. V(int semid):

    • 这个函数用于执行 V 操作,即释放资源。
    • 它的实现与 P() 函数类似,只是将 op.sem_op 设置为1,表示对信号量执行 V 操作。

2.信号量实现同步互斥 

交替实现奇偶数打印,打印一个奇数后必须是一个偶数

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>#define KEY 1234 // 信号量的键值// 定义一个联合体,用于semctl初始化
union semun {int val;struct semid_ds *buf;unsigned short *array;
};// 创建一个信号量并初始化为1
int create_semaphore() 
{int semid = semget(KEY, 1, IPC_CREAT | 0666); // 创建一个信号量集,包含1个信号量if (semid == -1) {perror("semget");exit(1);}union semun arg;arg.val = 0; // 初始值为0if (semctl(semid, 0, SETVAL, arg) == -1) // 初始化信号量{ perror("semctl");exit(1);}return semid;
}// P操作(等待资源)
void P(int semid) 
{struct sembuf op;op.sem_num = 0; // 信号量集中的第一个信号量op.sem_op = -1; // 对信号量执行P操作op.sem_flg = 0;if (semop(semid, &op, 1) == -1) {perror("semop");exit(1);}
}// V操作(释放资源)
void V(int semid) 
{struct sembuf op;op.sem_num = 0; // 信号量集中的第一个信号量op.sem_op = 1; // 对信号量执行V操作op.sem_flg = 0;if (semop(semid, &op, 1) == -1) {perror("semop");exit(1);}
}int main() 
{int  i = 1;int j = 2;int semid = create_semaphore(); // 创建信号量pid_t pid = fork(); // 创建子进程if (pid == -1) {perror("fork");exit(1);}if (pid == 0)  // 子进程打印奇数{while(1){ 		printf("i = %d\n",i);i += 2;V(semid); // 释放资源sleep(1);}       } else // 父进程打印偶数{while(1){P(semid); // 等待资源printf("j = %d\n",j);j += 2;}		}return 0;
}

执行结果

i = 1
j = 2
i = 3
j = 4
i = 5
j = 6
i = 7
j = 8
i = 9
j = 10
i = 11
j = 12
i = 13
j = 14
i = 15
j = 16
 

五、消息队列

发送进程

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>#define MSG_KEY 1234 // 消息队列的键值// 定义消息结构体
struct msg_buffer 
{long msg_type; // 消息类型char msg_text[100]; // 消息内容
};int main() 
{int msgid;struct msg_buffer message_send;// 创建消息队列msgid = msgget(MSG_KEY, IPC_CREAT | 0666);if (msgid == -1) {perror("msgget");exit(1);}// 准备发送的消息strcpy(message_send.msg_text, "Hello, Message Queue!");message_send.msg_type = 1; // 消息类型为1// 发送消息if (msgsnd(msgid, &message_send, sizeof(message_send) - sizeof(long), 0) == -1) {perror("msgsnd");exit(1);}printf("Parent process sent message: %s\n", message_send.msg_text);return 0;
}

 接收进程

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>#define MSG_KEY 1234 // 消息队列的键值// 定义消息结构体
struct msg_buffer {long msg_type; // 消息类型char msg_text[100]; // 消息内容
};int main() 
{int msgid;struct msg_buffer message_rcv;// 创建消息队列msgid = msgget(MSG_KEY, IPC_CREAT | 0666);if (msgid == -1) {perror("msgget");exit(1);}// 接收消息if (msgrcv(msgid, &message_rcv, sizeof(message_rcv) - sizeof(long), 1, 0) == -1) {perror("msgrcv");exit(1);}printf("Child process received message: %s\n", message_rcv.msg_text);return 0;
}

执行结果:

./s

Parent process sent message: Hello, Message Queue!
./r
Child process received message: Hello, Message Queue!
 

在这两个示例代码中,主要使用了以下系统调用:

  1. msgget: 用于创建或打开一个消息队列。它接受一个参数,即消息队列的键值(一个唯一的标识符),并返回一个消息队列的标识符(msgid)。

  2. msgsnd: 用于向消息队列发送消息。它接受四个参数:消息队列的标识符(msgid)、指向要发送的消息的指针、消息的大小(不包括消息类型字段的大小)、消息的标志(通常为0)。

  3. msgrcv: 用于从消息队列接收消息。它接受五个参数:消息队列的标识符(msgid)、指向用于接收消息的缓冲区的指针、缓冲区大小(不包括消息类型字段的大小)、消息类型(通常为正整数)、接收消息的标志(通常为0)。

  4. msgctl: 用于控制消息队列的属性,如删除消息队列。在这个示例中,我们使用它来删除消息队列。它接受三个参数:消息队列的标识符(msgid)、命令(IPC_RMID 表示删除消息队列)、指向用于控制消息队列属性的结构体的指针(在这个例子中不需要)。

六、套接字

网络部分的内容

相关文章:

【Linux】进程间通信IPC机制

目录 一、无名管道 二、有名管道 三、共享内存 四、信号量 五、消息队列 六、套接字 一、无名管道 1.只能用于具有亲缘关系的进程之间的通信(也就是父子进程或者兄弟进程)。 2.是一个单工的通信模式&#xff0c;具有固定的读端和写端。 3.管道也可以看成是一种特殊的文件…...

【如此简单!数据库入门系列】之效率基石 -- 磁盘空间管理

文章目录 1 前言2 磁盘空间管理3 磁盘空间管理的实现4 存储对象关系5 总结6 系列文章 1 前言 如何将表中的记录存储在物理磁盘上呢&#xff1f; 概念模式中&#xff0c;记录&#xff08;Record&#xff09;表示表中的一行数据&#xff0c;由多个列&#xff08;字段或者属性&…...

专业渗透测试 Phpsploit-Framework(PSF)框架软件小白入门教程(五)

本系列课程&#xff0c;将重点讲解Phpsploit-Framework框架软件的基础使用&#xff01; 本文章仅提供学习&#xff0c;切勿将其用于不法手段&#xff01; 继续接上一篇文章内容&#xff0c;讲述如何进行Phpsploit-Framework软件的基础使用和二次开发。 在下面的图片中&#…...

5月7日监控二叉树+斐波那契数

968.监控二叉树 给定一个二叉树&#xff0c;我们在树的节点上安装摄像头。 节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。 计算监控树的所有节点所需的最小摄像头数量。 示例 1&#xff1a; 输入&#xff1a;[0,0,null,0,0] 输出&#xff1a;1 解释&#xff…...

C++类的设计编程示例

一、银行账户类 【问题描述】 定义银行账户BankAccount类。 私有数据成员&#xff1a;余额balance&#xff08;整型&#xff09;。 公有成员方法&#xff1a; 无参构造方法BankAccount()&#xff1a;将账户余额初始化为0&#xff1b; 带参构造方法BankAccount(int m)&#xff1…...

YOLOv5 V7.0 - rknn模型的验证 输出精度(P)、召回率(R)、mAP50、mAP50-95

1.简介 RKNN官方没有提供YOLOv5模型的验证工具&#xff0c;而YOLOv5自带的验证工具只能验证pytorch、ONNX等常见格式的模型性能&#xff0c;无法运行rknn格式。考虑到YOLOv5模型转换为rknn会有一定的精度损失&#xff0c;但是需要具体数值才能进行评估&#xff0c;所以需要一个…...

CUDA、CUDNN、Pytorch三者之间的关系

这个东西嘛&#xff0c;我一开始真的是一头雾水&#xff0c;安装起来真是麻烦死了。但是随着要复现的项目越来越多&#xff0c;我也不得不去学会他们是什么&#xff0c;以及他们之间的关系。 首先&#xff0c;一台电脑里面允许有多种版本的cuda存在&#xff0c;然后cuda分为run…...

vue-cli2,vue-cli3,vite 生产环境去掉console.log

console.log一般都是在开发环境下使用的&#xff0c;在生产环境下需要去除 &#xff0c;如果手动删除未免也太累了&#xff0c;我们可以用插件对于具体环境全局处理。 vue-cli2 项目build 下面webpack.prod.config.js 文件中: plugins: [new webpack.DefinePlugin({process.en…...

Docker-Compose编排LNMP并部署WordPress

前言 随着云计算和容器化技术的快速发展&#xff0c;使用 Docker Compose 编排 LNMP 环境已经成为快速部署 Web 应用程序的一种流行方式。LNMP 环境由 Linux、Nginx、MySQL 和 PHP 组成&#xff0c;为运行 Web 应用提供了稳定的基础。本文将介绍如何通过 Docker Compose 编排 …...

附录C:招聘流程

< 回到目录 附录C&#xff1a;招聘流程 _xxx_公司的招聘 使命 只雇佣顶级人才。 他们是能够胜任工作&#xff0c;并与 _&#xff08;你的公司名称&#xff09;_ 的企业文化相匹配的超级明星。 方法 记分卡。招聘经理创建一份文件&#xff0c;详细描述此职位的工作内容…...

1688快速获取整店铺列表 采集接口php Python

在电子商务的浪潮中&#xff0c;1688平台作为中国领先的批发交易平台&#xff0c;为广大商家提供了一个展示和销售商品的广阔舞台&#xff1b;然而&#xff0c;要在众多店铺中脱颖而出&#xff0c;快速获取商品列表并进行有效营销是关键。 竞争对手分析 价格比较&#xff1a;…...

CTF-WEB(MISC)

安全攻防知识——CTF之MISC - 知乎 CTF之MISC杂项从入门到放弃_ctf杂项 你的名字-CSDN博客 CTF MICS笔记总结_archpr 掩码攻击-CSDN博客 一、图片隐写 CTF杂项---文件类型识别、分离、合并、隐写_ctf图片分离-CSDN博客 EXIF&#xff08;Exchangeable Image File&#xff09;是…...

Ubuntu如何更换 PyTorch 版本

环境&#xff1a; Ubuntu22.04 WLS2 问题描述&#xff1a; Ubuntu如何更换 PyTorch 版本考虑安装一个为 CUDA 11.5 编译的 PyTorch 版本。如何安装旧版本 解决方案&#xff1a; 决定不升级CUDA版本&#xff0c;而是使用一个与CUDA 11.5兼容的PyTorch版本&#xff0c;您可…...

python flask css样式无效

解释&#xff1a; Flask是一个Python的轻量级Web框架&#xff0c;它没有为CSS提供任何内置的支持。如果你在Flask项目中引入了CSS文件&#xff0c;但是这个CSS没有生效&#xff0c;可能的原因有&#xff1a; 路径不正确&#xff1a;你的CSS文件没有放在正确的目录下&#xff0…...

大数据学习笔记14-Hive基础2

一、数据字段类型 数据类型 &#xff1a;LanguageManual Types - Apache Hive - Apache Software Foundation 基本数据类型 数值相关类型 整数 tinyint smallint int bigint 小数 float double decimal 精度最高 日期类型 date 日期 timestamps 日期时间 字符串类型 s…...

vue3 下载图片(包括多图片下载)

单图片下载 //使用 download(https://img1.baidu.com/it/u1493209339,2544178769&fm253&app138&sizew931&n0&fJPEG&fmtauto?sec1715101200&t854f3434686cfd2cba9d6a528597d15c)//下载逻辑 const download async (modelUrl) > {const respons…...

LabVIEW如何通过子VI更改主VI控件属性?

在LabVIEW中&#xff0c;可以通过使用Local Variable或Property Node来实现主VI控件属性的更改。这些方法可以在主VI和子VI之间传递数据和控件属性。 Local Variable: 使用Local Variable可以在子VI中直接访问并修改主VI中的控件属性。在子VI中创建Local Variable&#xff0c;并…...

关于MS-DOS时代的回忆

目录 一、MS-DOS是什么&#xff1f; 二、MS-DOS的主要功能有哪些&#xff1f; 三、MS-DOS的怎么运行的&#xff1f; 四、微软开源MS-DOS源代码 五、高手与漂亮女同学 一、MS-DOS是什么&#xff1f; MS-DOS&#xff08;Microsoft Disk Operating System&#xff09;是微软公…...

数据库索引(Mysql)

简述:数据库索引是加速数据检索,提高查询效率的一种数据结构 语法规则 创建索引 --通用语法规则 --[内容] 可选参数 --UNIQUE: 可选关键字&#xff0c;用于创建唯一索引&#xff0c;确保索引列的值是唯一的 CREATE [UNIQUE] INDEX 索引名 ON 表名(字段名,...) [ASC | DESC];…...

异常-Exception

异常介绍 基本概念 Java语言中&#xff0c;将程序执行中发生的不正常情况称为“异常”。&#xff08;开发过程中的语法错误和逻辑错误不是异常&#xff09;执行过程中所发生的异常事件可分为两大类 1&#xff0c;Error&#xff08;错误&#xff09;&#xff1a;Java虚拟机无法…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

通过MicroSip配置自己的freeswitch服务器进行调试记录

之前用docker安装的freeswitch的&#xff0c;启动是正常的&#xff0c; 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

ubuntu22.04有线网络无法连接,图标也没了

今天突然无法有线网络无法连接任何设备&#xff0c;并且图标都没了 错误案例 往上一顿搜索&#xff0c;试了很多博客都不行&#xff0c;比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动&#xff0c;重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...