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

Linux进程7-signal信号处理方式验证、可重入函数举例、信号集函数验证、信号集阻塞验证

目录

1. signal函数 

1.1进程接收到信号后的处理方式

1.2 signal 函数

1.2.1 signal 函数默认处理

1.2.2 signal 函数忽略处理

1.2.3 signal 函数自定义处理

1.2.4 signal 函数返回值 

2.可重入函数

2.1如何判断函数是否可重入

2.2自定义信号处理函数举例

2.2.1 sleep

2.2.2 alarm

2.2.3 read

2.2.4 lseek

3.信号集

3.1. ‌基本概念与作用‌

3.2. ‌核心API函数‌

3.2.1 sigemptyset

 3.2.2 sigfillset 

3.2.3 sigismember

 3.2.4 sigaddset

3.2.5 sigdelset

3.3 程序验证

4.信号阻塞集

4.1函数原型


1. signal函数 

1.1进程接收到信号后的处理方式

1 、执行系统默认动作
2 、忽略此信号
3 、执行自定义信号处理函数 。程序中可用函数 signal() 改变信号的处理方式。
注意:SIGKILL和SIGSTOP这两个信号 只能以默认的方式处理,不能忽略或者捕捉( 执行自定义信号处理函数 )。

1.2 signal 函数

signal 函数原型:

#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum,sighandler_t handler);功能:
注册信号处理函数(不可用于 SIGKILL、SIGSTOP 信号),
即确定收到信号后处理函数的入口地址。参数:
signum:信号编号
handler 的取值:忽略该信号:SIG_IGN执行系统默认动作:SIG_DFL自定义信号处理函数:信号处理函数名返回值:
成功:返回函数地址,该地址为此信号上一次注册的信号处理函数的地址。
失败:返回 SIG_ERR

1.2.1 signal 函数默认处理

程序:

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <stdlib.h>int main()
{int num = 0;//以默认的方式处理信号//终端按下 Ctrl + C if(signal(SIGINT, SIG_DFL) == SIG_ERR){perror("fail to signal");exit(1);}else if(signal(SIGQUIT, SIG_DFL) == SIG_ERR){  //终端按下 Ctrl + \ perror("fail to signal");exit(1);}  else if(signal(SIGTSTP, SIG_DFL) == SIG_ERR){  //终端按下 Ctrl + z perror("fail to signal");exit(1);}else{}while(1){num++;printf("程序运行第 %d 次\n", num);sleep(2);}return 0;
}

运行结果:分别运行 ./a.out,执行不同的终止信号。

1.2.2 signal 函数忽略处理

程序:

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <stdlib.h>int main()
{int num = 0;//以默认的方式处理信号//终端按下 Ctrl + C if(signal(SIGINT, SIG_IGN) == SIG_ERR){perror("fail to signal");exit(1);}else if(signal(SIGQUIT, SIG_IGN) == SIG_ERR){  //终端按下 Ctrl + \ perror("fail to signal");exit(1);}  else if(signal(SIGTSTP, SIG_IGN) == SIG_ERR){  //终端按下 Ctrl + z perror("fail to signal");exit(1);}else{}while(1){num++;printf("程序运行第 %d 次\n", num);sleep(3);}return 0;
}

运行结果:信号已忽略的方式执行,终端输入终止命令,程序还会一直运行。

程序只能在另外一个终端,执行kill 命令终止运行进程。

1.2.3 signal 函数自定义处理

程序:

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <stdlib.h>void handler(int sig) 
{if(sig == SIGINT){printf("终端按下 Ctrl + C ,信号编号(%d)\n", sig);}else if(sig == SIGQUIT){printf("终端按下 Ctrl + \\ ,信号编号(%d)\n", sig);}else if(sig == SIGTSTP){printf("终端按下 Ctrl + z ,信号编号(%d)\n", sig);} 
}int main()
{int num = 0;//以自定义的方式处理信号//终端按下 Ctrl + C if(signal(SIGINT, handler) == SIG_ERR){perror("fail to signal");exit(1);}else if(signal(SIGQUIT, handler) == SIG_ERR){  //终端按下 Ctrl + \ perror("fail to signal");exit(1);}  else if(signal(SIGTSTP, handler) == SIG_ERR){  //终端按下 Ctrl + z perror("fail to signal");exit(1);}else{}while(1){num++;printf("程序运行第 %d 次\n", num);sleep(3);}return 0;
}

运行结果:程序执行对应的自定义函数。

1.2.4 signal 函数返回值 

程序:

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <stdlib.h>typedef void (*sighandler_t)(int);
sighandler_t old_handler;//自定义信号处理
void handler(int sig)
{printf(" 自定义信号处理 信号编号: %d\n", sig);//使用原 old_handler默认处理函数执行if(signal(SIGINT, old_handler) == SIG_ERR){perror("fail to signal");exit(1);}
}int main() 
{int num = 0;// 注册 SIGINT 处理函数,并保存原处理函数地址(默认处理)old_handler = signal(SIGINT, handler);//signal()函数的返回值是signal()函数上一次的行为//old_handler 保存的是 默认处理函数 SIG_DEF 地址//SIGINT :终端按下 Ctrl + C 终止if (old_handler == SIG_ERR) {perror("signal() failed");exit(1);}while(1){num++;printf("程序运行第 %d 次\n", num);sleep(2);}return 0;
}

运行结果:程序运行后,main函数第一次收到Ctrl + C 终止信号,会先执行自定义信号处理函数(signal函数,第二个参数传参不为:默认、忽略处理,传入了自定义处理函数)。在自定义处理函数中,第二次收到Ctrl + C 终止信号,执行上次 信号默认处理方式(main函数第一次signal函数的返回值,为 信号信号默认处理入口地址)终止程序运行。

2.可重入函数

可重入函数‌是一种在多线程或中断场景下能够安全并发执行的函数,其核心特性在于不会因多次调用导致数据竞争或状态混乱。
编写可重入函数:
1、不使用(返回)静态的数据、全局变量(除非用信号量互斥)。
2、不调用动态内存分配、释放的函数。
3、不调用任何不可重入的函数(如标准 I/O 函数)。
注:
即使信号处理函数使用的都是可重入函数(常见的可重入函数),也要注意进入处理函数时,首先要保存 errno 的值,结束时,再恢复原值。因为,信号处理过程中,errno 值随时可能被改变。

可重入函数与不可重入函数的区别

特性可重入函数不可重入函数
数据存储使用局部变量或参数依赖全局/静态变量或共享资源
线程安全性支持多线程并发调用可能导致数据竞争或状态错乱
示例函数localtime_rstrtok_rlocaltimestrtok

2.1如何判断函数是否可重入

(1)查阅文档 man 手册中会明确标注函数是否为异步信号安全(Async-Signal-Safe)。
例如: man 7 signal # 查看信号安全的函数列表
终端执行: man 7 signal > signal.txt 命令,将数据重定向到signal.txt,查看
(2)POSIX 标准中,以 _r 结尾的函数通常是可重入的(如 strtok_r)。

2.2自定义信号处理函数举例

2.2.1 sleep

程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>void handler(int sig)
{printf(" Ctrl + C 自定义信号处理函数执行 \n");
}int main(int argc, char *argv[])
{int num = 0;// SIGINT :终端按下 Ctrl + C 终止signal(SIGINT, handler);//sleep是一个可重入函数,但是当执行信号处理函数之后,不会回到原本的位置继续睡眠sleep(10);printf("sleep 结束\n");//alarm函数是一个可重入函数,当他执行时,如果有信号产生并执行信号处理函数,执行完毕后,会继续运行//alarm(10);while(1){num++;printf("程序运行第 %d 次\n", num);sleep(1);}return 0;
}

运行结果:程序运行时,先睡眠10s,在执行后续程序。在睡眠3s时终端按下 ctrl+c 终止命令,直接执行完自定义信号处理函数,sleep(10)也运行结束,直接执行while(1)里面的程序。

2.2.2 alarm

程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>void handler(int sig)
{printf(" Ctrl + C 自定义信号处理函数执行 \n");
}int main(int argc, char *argv[])
{int num = 0;// SIGINT :终端按下 Ctrl + C 终止signal(SIGINT, handler);//sleep是一个可重入函数,但是当执行信号处理函数之后,不会回到原本的位置继续睡眠//sleep(10);//alarm函数是一个可重入函数,当他执行时,如果有信号产生并执行信号处理函数,执行完毕后,会继续运行alarm(10);while(1){num++;printf("程序运行第 %d 次\n", num);sleep(1);}return 0;
}

运行结果:程序运行3秒后,按下ctrl + c终止信号,handler函数执行结束,回到alarm函数继续运行,由于alarm闹钟定时10秒程序运行结束,所以程序继续运行7秒后退出。

2.2.3 read

程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>void handler(int sig)
{printf(" Ctrl + C 自定义信号处理函数执行 \n");
}int main(int argc, char *argv[])
{// SIGINT :终端按下 Ctrl + C 终止signal(SIGINT, handler);char buf[32] = "";//read也是一个可重入函数,在等待终端输入时,如果产生信号并执行信号处理函数,信号处理//函数执行完毕后,可以继续输入数据,read可以读取到信号处理函数之后的数据if(read(0, buf, 20) == -1)//从终端读取内容,0:stdin 标准输入{perror("fail to read");exit(1);}printf("buf = [%s]\n", buf);return 0;
}

运行结果:文件IO read函数从终端读取输入的数据,按下ctrl + c终止信号,handler函数执行结束,回到read函数继续运行,再次输入数据,按下回车,读取到的数据为最后一次数据的数据。

2.2.4 lseek

程序1:

#include <signal.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int fd;//信号自定义处理函数,调用 lseek 实现定时调整文件偏移量
void handler(int sig)  
{//重定位偏移量为SEEK_END 文件末尾int len2 = lseek(fd, 0, SEEK_END); printf("总偏移量:%ld !\n", len2);exit(1);
}int main() 
{//读写打开//fd = open("./file1.txt", O_RDWR);//只写打开,不存在创建,存在清0fd = open("./file2.txt", O_WRONLY | O_CREAT | O_TRUNC, 0664);if (-1 == fd){perror("fail to open file ");return -1;}//handler 信号的自定义处理函数signal(SIGALRM, handler);alarm(3);  // 3秒后触发一次 SIGALRM信号int len1 = 5;int len = 0;while (1) {//lseek(fd, 0, SEEK_SET);//从开头位置偏移len1个位置len = lseek(fd, len1, SEEK_SET);len1+=len;printf("偏移量len:%ld ,下次开始偏移位置设置len1:%ld!\n",len, len1);write(fd, "abcd", 4);//文件IO操作,写入数据sleep(1);}return 0;
}

运行结果:在alarm闹钟信号到达后,在信号自定义处理函数,调用 lseek 实现定时调整文件偏移量。

文本中写入的数据:最后一次写入完abcd的偏移量为24.

程序2:

#include <signal.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int fd;//信号自定义处理函数,调用 lseek 实现定时调整文件偏移量
void handler(int sig)  
{//重定位偏移量为SEEK_END 文件末尾int len2 = lseek(fd, 0, SEEK_END); printf("总偏移量:%ld !\n", len2);//重定位偏移量为SEEK_SET 文件开头len2 = lseek(fd, 0, SEEK_SET); printf("读取偏移量:%ld !\n", len2);char buf[64] = {0};ssize_t  num = read(fd, buf, sizeof(buf));// printf("strlen(buf) = %d\n", strlen(buf));printf("read size = %d\n", num);//读取字节大小printf("read buf = %s\n", buf);close(fd);  	 	exit(1);//退出
}int main() 
{//读写打开//fd = open("./file1.txt", O_RDWR);//读写打开,不存在创建,存在清0fd = open("./file2.txt", O_RDWR | O_CREAT | O_TRUNC, 0664);if (-1 == fd){perror("fail to open file ");return -1;}//handler 信号的自定义处理函数signal(SIGALRM, handler);alarm(3);  // 3秒后触发一次 SIGALRM信号int len1 = 0;int len = 0;while (1) {//lseek(fd, 0, SEEK_SET);//从开头位置偏移len1个位置len = lseek(fd, len1, SEEK_SET);len1+=5;printf("偏移量len: %ld ,下次开始偏移位置设置len1: %ld \n",len, len1);write(fd, "abcd ", 5);//文件IO操作,写入数据sleep(1);}return 0;
}

运行结果:main函数向txt文本写入数据,在alarm闹钟信号到达后,在信号自定义处理函数,调用 lseek 实现定时调整文件偏移量,使用read函数读取内容。

3.信号集

3.1. ‌基本概念与作用‌

信号集(Signal Set)是Linux中用于批量管理信号的数据结构,本质为位掩码(bitmask),每个bit对应一种信号状态。POSIX标准定义了sigset_t数据类型来表示信号集。

主要作用包括: ‌

  • 信号屏蔽‌:通过设置阻塞信号集,控制进程/线程对特定信号的响应
  • 状态查询‌:通过未决信号集(pending)查看已产生但未处理的信号 ‌
  • 批量操作‌:支持对多个信号进行统一处理,如初始化、添加、删除等

sigset.h存储路径:终端输出 sudo find /usr/include -name "sigset.h"

sigset_t是一个数组:

3.2. ‌核心API函数

函数功能示例场景
sigemptyset()初始化空信号集创建新信号集前的初始化操作
sigfillset()初始化包含所有信号的完全集需要屏蔽所有信号时使用
sigaddset()向信号集添加指定信号选择性屏蔽SIGINT/SIGTERM等信号
sigdelset()从信号集移除指定信号解除对特定信号的阻塞
sigismember()检查信号是否在集合中调试时验证信号集状态
sigprocmask()修改进程级信号屏蔽字主进程全局信号控制
pthread_sigmask()修改线程级信号屏蔽字多线程环境下隔离信号处理
sigwait()阻塞等待指定信号到达异步事件同步化处理

3.2.1 sigemptyset

初始化一个空的信号集#include <signal.h>
int sigemptyset(sigset_t *set);功能:
初始化由 set 指向的信号集,清除其中所有的信号即初始化一个空信号集。参数:
set:信号集标识的地址,以后操作此信号集,对 set 进行操作就可以了。返回值:
成功返回 0,失败返回 -1。

 3.2.2 sigfillset 

初始化一个满的信号集
#include <signal.h>
int sigfillset(sigset_t *set);功能:
初始化信号集合 set, 将信号集合设置为所有信号的集合。参数:
信号集标识的地址,以后操作此信号集,对 set 进行操作就可以了。返回值:
成功返回 0,失败返回 -1。

3.2.3 sigismember

判断某个集合中是否有某个信号
#include <signal.h>
int sigismember(const sigset_t *set,int signum);功能:
查询 signum 标识的信号是否在信号集合 set 之中。参数:
set:信号集标识符号的地址。
signum:信号的编号。返回值:
在信号集中返回 1,不在信号集中返回 0
错误,返回 -1

 3.2.4 sigaddset

向某个集合中添加一个信号
#include <signal.h>
int sigaddset(sigset_t *set, int signum);功能:
将信号 signum 加入到信号集合 set 之中。参数:
set:信号集标识的地址。
signum:信号的编号。返回值:
成功返回 0,失败返回 -1。

3.2.5 sigdelset

从某个信号集中删除一个信号
#include <signal.h>
int sigdelset(sigset_t *set, int signum);功能:
将 signum 所标识的信号从信号集合 set 中删除。参数:
set:信号集标识的地址。
signum:信号的编号。返回值:
成功:返回 0
失败:返回 -1

3.3 程序验证

程序:

#include <signal.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main(int argc, char *argv[])
{//创建一个信号集sigset_t set;int ret = 0;//初始化一个空的信号集sigemptyset(&set);printf("判断SIGINT信号是否在信号集中\n");//判断SIGINT信号是否在信号集中ret = sigismember(&set, SIGINT);if(ret == 0){printf("SIGINT该信号不在信号集 \n ret = %d\n", ret);}	//判断SIGQUIT信号是否在信号集中ret = sigismember(&set, SIGQUIT);if(ret == 0){printf("SIGQUIT该信号不在信号集 \n ret = %d\n", ret);}	printf("将指定的信号添加到信号集中\n");//将指定的信号添加到信号集中sigaddset(&set, SIGINT);sigaddset(&set, SIGQUIT);ret = sigismember(&set, SIGINT);if(ret == 1){	printf("SIGINT该信号在信号集 \n ret = %d\n", ret);}ret = sigismember(&set, SIGQUIT);if(ret == 1){	printf("SIGQUIT该信号在信号集 \n ret = %d\n", ret);}printf("将指定的信号删除\n");ret =  sigdelset(&set, SIGQUIT);if(ret == 0){	printf("SIGQUIT信号已在信号集删除 \n ret = %d\n", ret);}ret = sigismember(&set, SIGQUIT);if(ret == 0){printf("SIGQUIT该信号不在信号集 \n ret = %d\n", ret);}	return 0;
}

运行结果:

4.信号阻塞集

信号阻塞集是 Linux 进程或线程用来控制哪些信号会被暂时阻塞的机制。被阻塞的信号不会立即递送给进程,而是进入“未决(Pending)”状态,直到解除阻塞后才被处理

4.1函数原型

#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);功能:
检查或修改信号阻塞集,根据 how 指定的方法对进程的阻塞集合进行修改,
新的信号阻塞集由 set 指定,而原先的信号阻塞集合由 oldset 保存。参数:how:操作类型:SIG_BLOCK:将 set 中的信号加入当前阻塞集(取并集)。SIG_UNBLOCK:将 set 中的信号从当前阻塞集中移除。SIG_SETMASK:直接将当前阻塞集替换为 set。set:要操作的信号集(若为 NULL,则 how 参数无效)。oldset:返回旧的阻塞集(可传 NULL)。

程序:

#include <signal.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main(int argc, char *argv[])
{int i=0;//创建信号集并在信号集中添加信号sigset_t set;//创建一个信号集sigemptyset(&set);//初始化一个空的信号集sigaddset(&set, SIGINT);//将SIGINT信号添加到set信号集中while(1){//将set信号集添加到信号阻塞集中sigprocmask(SIG_BLOCK, &set, NULL);for(i=0; i<5; i++){printf(" SIGINT:ctrl+c 信号还在阻塞集中,不响应\n");sleep(2);}//将set信号集从信号阻塞集中删除sigprocmask(SIG_UNBLOCK, &set, NULL);for(i=0; i<5; i++){printf(" SIGINT:ctrl+c 信号已不在阻塞集中,可以立即响应\n");sleep(2);}}return 0;
}

运行结果:(1)未退出阻塞集,按下终止信号ctrl+c,等待退出阻塞集,立即响应,程序运行结束。

(2)已退出阻塞集,按下终止信号ctrl+c,立即响应,程序运行结束。

相关文章:

Linux进程7-signal信号处理方式验证、可重入函数举例、信号集函数验证、信号集阻塞验证

目录 1. signal函数 1.1进程接收到信号后的处理方式 1.2 signal 函数 1.2.1 signal 函数默认处理 1.2.2 signal 函数忽略处理 1.2.3 signal 函数自定义处理 1.2.4 signal 函数返回值 2.可重入函数 2.1如何判断函数是否可重入 2.2自定义信号处理函数举例 2.2.1 sle…...

使用Python在excel里创建柱状图

一、前言 通过使用Python的openpyxl库&#xff0c;在excel里创建柱状图。openpyxl库提供了创建Excel图表的功能&#xff0c;包括柱状图(Bar Chart)。 二、程序展示 1、导入相关模块&#xff0c;新建excel 新建excel后&#xff0c;在excel的第一列创建一些数据。 import op…...

计算机视觉进化论:YOLOv12、YOLOv11与Darknet系YOLOv7的微调实战对比

摘要 YOLO系列作为实时目标检测领域的重要里程碑&#xff0c;持续引领速度与精度的平衡发展。本文围绕YOLOv7&#xff08;基于Darknet框架&#xff09;、YOLOv11及YOLOv12&#xff0c;系统、深入地对比了三款模型的架构创新、微调策略、核心技术及应用场景。我们详细解析了三者…...

湖北理元理律师事务所:债务管理领域的平台化创新探索

随着中国居民负债率攀升至62%&#xff08;央行2023年数据&#xff09;&#xff0c;债务管理从个体需求演变为社会性课题。湖北理元理律师事务所通过“法律科技金融”的融合模式&#xff0c;构建了国内首个全链条债务管理平台&#xff0c;其服务逻辑与行业价值值得深度剖析。 平…...

沐曦玩转 LMDeploy、XTuner 和 InternLM3

学习链接&#xff1a; https://aicarrier.feishu.cn/wiki/O84LwkiBriUU0NkDwurcSufhnVb 一 LMDeploy推理及验证 1.1 下载LMDeploy # 安装addict软件包 pip install addict mmengine mmengine-lite fire accelerate0.32.1 nvidia-ml-py# 解决LMDeploy对tranformers版本要求的…...

【Java面试笔记:进阶】26.如何监控和诊断JVM堆内和堆外内存使用?

监控和诊断JVM内存使用是优化性能和解决内存问题的关键。 1.JVM内存监控与诊断方法 1.图形化工具 JConsole:提供图形化界面,可直接连接到Java进程,查看内存使用情况。VisualVM:功能强大的图形化工具,但注意从Oracle JDK 9开始不再包含在JDK安装包中。Java Mission Contr…...

阿里云服务器云盘扩容

在阿里云服务器上在线扩容了云盘后&#xff0c;如果服务器内部查看容量没有变化&#xff0c;可能是由于分区和文件系统未正确扩展。以下是详细的解决步骤&#xff1a; 1. 确认扩容是否成功 在阿里云控制台检查磁盘容量是否已显示扩容后的新大小。如果控制台显示已扩容&#x…...

【ESP32】st7735s + LVGL移植

LVGL的移植 使用版本1、创建工程2、开始移植2.1、文件准备2.2、修改代码2.3、SDK配置编辑器 3、测试 使用版本 LVGL版本&#xff1a;8.3 链接点这里ESPIDF版本&#xff1a;4.4.8lvgl_esp32_drivers&#xff1a; 链接点这里ESP32型号&#xff1a;ESP32S3 1、创建工程 默认都会…...

Jackson 使用方法详解

Jackson 是 Java 生态中最流行的 JSON 处理库&#xff0c;也是 Spring Boot 的默认 JSON 解析器。它提供了高性能的 JSON 序列化&#xff08;对象 → JSON&#xff09;和反序列化&#xff08;JSON → 对象&#xff09;功能。以下是 Jackson 的全面使用指南。 1. 基础依赖 Mave…...

TensorFlow深度学习框架:从入门到精通的完整指南

&#x1f31f; TensorFlow核心优势 TensorFlow作为Google开发的顶级深度学习框架&#xff0c;具有三大独特优势&#xff1a; 工业级部署能力&#xff1a;支持从移动端到服务器的全平台部署完善的工具链&#xff1a;包含TensorBoard、TF Lite、TF.js等完整生态强大的社区支持&…...

Java 入门宝典--注释、关键字、数据类型、变量常量、类型转换

作者&#xff1a;IvanCodes 发布时间&#xff1a;2025年4月28日&#x1f423; 专栏&#xff1a;Java教程 哈喽&#xff0c;各位 CSDN 的小伙伴们&#xff01;&#x1f44b; 这部分内容虽然基础&#xff0c;但 极其重要&#xff0c;是后续学习所有高级特性的基石。准备好了吗&…...

【含文档+PPT+源码】基于微信小程序的旅游论坛系统的设计与实现

项目介绍 本课程演示的是一款基于微信小程序的旅游论坛系统的设计与实现&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套系统 …...

Android开发,实现一个简约又好看的登录页

文章目录 1. 编写布局文件2.设计要点说明3. 效果图4. 关于作者其它项目视频教程介绍 1. 编写布局文件 编写activity.login.xml 布局文件 <?xml version"1.0" encoding"utf-8"?> <androidx.appcompat.widget.LinearLayoutCompat xmlns:android…...

一种改进的YOLOv11网络,用于无人机视角下的小目标检测

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 随着无人机&#xff08;UAV&#xff09;和计算机视觉技术的快速发展&#xff0c;从无人机视角进行目标检测已成为一个重要的研究领域。然而&#xff0c;无人机图像中目标像素占比极小、物体尺度变…...

linux离线安装zsh

下载zsh 下载仓库后解压 下载地址&#xff1a;https://github.com/zsh-users/zsh 离线安装 安装方法见INSTALL文件 ./configure --prefix[/usr/local] make make install...

Golang|使用函数作为参数和使用接口的联系

函数作为数据类型的一种&#xff0c;可以成为其他函数的参数。在 Go&#xff08;Golang&#xff09; 中&#xff0c;函数作为参数 和 接口&#xff08;interface&#xff09;&#xff0c;本质上都和抽象、灵活调用有关 —— 都是让代码更灵活、更可扩展的手段。不过它们各有侧重…...

Python爬虫实战:获取软科网最新特定专业大学排名数据并做分析,为高考填报志愿做参考

一、引言 在高考升学的重要阶段,志愿填报成为考生和家长关注的核心问题。准确、全面且具有权威性的大学专业排名数据,是考生做出科学志愿决策的关键依据。软科网作为专业的大学排名信息发布平台,其发布的计算机科学与技术专业排名数据,因具有较高的公信力和参考价值,备受…...

【ACL系列论文写作指北12-Deadline管理与科研项目规划】-用节奏赢得高质量科研

科研不是一场冲刺&#xff0c;而是有序推进的系统工程。 引言&#xff1a;掌控时间&#xff0c;才能掌控科研主动权 再好的想法和技术&#xff0c;如果没有良好的时间管理&#xff0c;最终只会沦为“赶DDL”的牺牲品。科研项目规划&#xff0c;是确保质量、效率与心态平衡的关…...

elasticsearch底层模块解析与实践系列

#作者&#xff1a;猎人 文章目录 底层模块深入解析之threadpool1、线程池2、线程池类型3、cpu core数量设置 底层模块深入解析之plugin底层模块深入解析之es node节点角色1、node类型2、master eligible node3、data node4、ingest node5、cooridnating only node6、node data…...

Git-基本操作

前言 安装 git --version sudo apt-get remove git -y #卸载 sudo apt-get install git -y基本操作 创建本地仓库 mkdir gitcodegit init 这个就可以创建本地仓库了 然后当前目录下就有一个.git的文件夹 配置本地仓库 就是配置用户的名称&#xff0c;和用户的email地址 在…...

iVX 图形化编程如何改写后端开发新范式

在数字化转型加速推进的当下&#xff0c;企业对后端系统的需求呈现爆发式增长。Gartner 最新报告指出&#xff0c;2025 年全球企业平均需完成 300 定制化应用开发&#xff0c;而传统编码模式下&#xff0c;单个项目平均交付周期长达 6 - 8 个月。与此同时&#xff0c;Redis、K…...

【数据可视化-42】杂货库存数据集可视化分析

&#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…...

使用 Electron 打包 Windows 可执行程序

使用 Electron 打包 Windows 可执行程序 在使用 Electron 构建桌面应用程序时&#xff0c;通常需要将项目打包为可执行文件&#xff08;例如 .exe 文件&#xff09;&#xff0c;以便用户可以方便地安装和运行。本文将介绍如何使用 electron-builder 将 Electron 项目打包成 Wi…...

爬虫学习笔记(三)--Http协议

思维导图 上面思维导图提取的原文是2026王道计网P286~290 URL最前面&#xff08;URL传输过程中遵循HTTP协议&#xff09; 协议 计算机传输的数据实际上就是二进制0和1&#xff0c;协议就是规定这一串二进制数字的前几位代表什么、中间几位代表什么、后几位代表什么 HTTP&a…...

ai环境cuda cudnn conda torch整体迁移 wsl docker

运行没问题的环境&#xff0c;wsl先关停wsl --shutdown 然后导出复制到迁移机器上wsl --export U24 E:\wsl\u24.tar 使用wsl版挂成虚拟机wsl --import U24 E:\wsl\ubuntu E:\wsl\u24.tar 使用docker版挂成镜像docker import E:\wsl\u24.tar my-ubuntu:custom 启动docker容器&am…...

数据库小技巧-使用开窗函数矫正数据库指定列部分列值重复的数据

需求描述 目前有某表的某列部分值重复&#xff0c;需要批量矫正该列数据&#xff0c;确保该列分组内不会出现重复值。 解决思路 -- 创建个临时表 create table t_tmp_20250428( c_bh varchar(32), -- 主键 c_bh_aj varchar(32), -- 主表外键&#xff0c;分组条件&#xff0c…...

【优选算法 | 二分查找】二分查找算法解析:如何通过二段性优化搜索效率

算法相关知识点可以通过点击以下链接进行学习一起加油&#xff01;双指针滑动窗口 在本篇文章中&#xff0c;我们将深入解析二分查找算法的核心原理。从基本概念到实际应用&#xff0c;带你了解如何利用二分查找高效定位元素&#xff0c;提升搜索效率。无论你是刚接触算法的新手…...

AI与IT协同的典型案例

简介 本篇代码示例展示了IT从业者如何与AI协同工作&#xff0c;发挥各自优势。这些案例均来自2025年的最新企业实践&#xff0c;涵盖了不同IT岗位的应用场景。 一、GitHub Copilot生成代码框架 开发工程师AI协作示例&#xff1a;利用GitHub Copilot生成代码框架&#xff0c;…...

5.软考高项(信息系统项目管理师)-成本管理

成本管理非常重要&#xff0c;选择、计算考得非常多&#xff0c;必须要好好学。 过程、输入、工具及输出 过程名&#xff08;附作用&#xff09; 通俗解释 输入 工具和技术 输出 规划成本管理 为如何管理项目成本提供指南和方向 编制成本管理计划&#xff0c;这个计划主…...

前端:纯HTML、CSS和JS菜单样式

实现了一个多级折叠菜单系统,使用纯HTML、CSS和JavaScript(无任何框架) 一、二级菜单展开 1、实现效果 初始状态-展示全部一级菜单 选中共状态,一级标题选中共为蓝色背景色,二级标题选中共为蓝色文字,展开右侧图标为-,后缩状态右侧图标为+ 2、实现 ​​HTML结构​​ …...

案例篇:如何用tcpdump和Wireshark识别潜在威胁

无论是日常浏览网页、观看视频&#xff0c;还是企业开展线上业务、进行数据传输&#xff0c;都离不开网络的支持。然而&#xff0c;网络问题也时有发生&#xff0c;比如网络卡顿&#xff0c;相信大家都遇到过&#xff0c;那种等待页面加载的焦急心情&#xff0c;真的让人抓狂。…...

微信小程序开发中关于首屏加载、本地数据持久化的思考

本文将围绕小程序开发中首屏性能优化与本地存储持久化两大重要主题展开&#xff0c;结合实际项目经验&#xff0c;系统分析常见问题、优化方法与最佳实践&#xff0c;构建流畅且高效的小程序体验。 文章目录 前言一、什么是首屏加载&#xff1f;为什么重要&#xff1f;二、小程…...

媒资管理之视频管理

一&#xff1a;业务概述&#xff1a; 媒资管理这个模块是我负责开发的&#xff0c;主要的管理对象是视频&#xff0c;图片&#xff0c;文档等 包括文件的上传&#xff0c;视频的处理&#xff0c;文件的删除 &#xff08;在媒资管理界面&#xff0c;有个上传视频的按钮&#…...

windows程序转鲲鹏服务器踩坑记【持续更新中】

1.鲲鹏处理器和Intel处理器的区别 处理器/对比项IntelKunpeng厂家因特尔(美国)华为(中国)指令集X86架构ARM-V8架构与指令集- x86 CISC复杂指令集 - 单核性能强&#xff08;如至强8380主频3.8GHz&#xff09; - 三级缓存优化&#xff0c;支持DDR4-3200和Optane内存- ARMv8-A RI…...

【阿里云大模型高级工程师ACP习题集】2.6.用插件扩展答疑机器人的能力边界

习题集: 【单选题】在构建Agent系统时,使用Assistant API创建Agent时,若想让Agent具备查询员工信息和发送请假申请的功能,以下对instructions参数设置最合理的是( ) A. “你可以做任何事情” B. “你能查询员工信息和发送请假申请” C. “你是公司助手,功能有:1.查询员…...

程序进程多任务线程

1.程序 程序(program)是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,也就是说程序是静态的代码。 2.进程 进程(process)是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。进程是操作系统资源分配和处理器调度的基本单位,拥有独立的代码、内部数…...

Finish技术生态计划: FinishRpc

finishRpc 简介 ​ 纯个人兴趣设计的项目: 因为失业在家摆烂 所以没事就想写点代码 本身也比较喜欢自己写一些好玩的demo 这个项目的设计完全是取悦自己又菜又有一个创造框架的梦想 可以用于提升框架设计思路以及实践一些常用技术的练习 可以用于校园中的练习 , 如果能对你有所…...

《商业世界的开源法则:协议选择与商业模式创新》

引言 在当今数字化时代&#xff0c;开源软件已成为技术生态系统中不可或缺的一部分。从Linux操作系统到Apache Web服务器&#xff0c;从MySQL数据库到React前端框架&#xff0c;开源项目支撑着全球大部分互联网基础设施和企业IT系统。然而&#xff0c;关于开源协议与商业使用之…...

Kubernetes》》k8s》》explain查 yaml 参数

在创建json 和yaml 时&#xff0c;我们可能不知道具体的参数该怎么写。同样 我们可以通过explain这个 命令来查看 每个参数具体的作用与写法 # 查看 pod类性有哪些参数 kubectl explain pod# 查看pod中 spec下面有哪些参数 kubectl explain pod.spec...

Kubernetes(k8s)学习笔记(三)--部署 Kubernetes Master

前文已经使用docker安装了kubeadm&#xff0c;因此本文使用kubeadm部署master节点。 一.先拉取必要的镜像库到本地。 在拉取之前&#xff0c;先配下镜像加速 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-EOF {"registry-mirrors": [&qu…...

《数据结构之美--二叉树》

一&#xff1a;引言&#xff1a; 上次我们学习了栈和队列这两个数据结构&#xff0c;今天我们来学习一个新的数据结构–二叉树中的堆。 堆其实就是一种特殊的二叉树&#xff0c;具有二叉树的性质的同时&#xff0c;还具有其他的性质。 那么在学习堆之前还是先来了解一下树。 …...

Prompt Engineering 提示工程:释放大语言模型潜力的关键技术与实践指南

提示工程:释放大语言模型潜力的关键技术与实践指南 提示工程(Prompt Engineering)作为与大型语言模型(LLM)交互的核心技术,已成为AI应用开发的关键技能。本文将系统介绍提示工程的定义与发展历程,深入剖析其核心知识点,提供实用的设计框架与技巧,并通过丰富的实战案例展示…...

std::print 和 std::println

一、基本概念 std::print 和 std::println 是 C23 新增的格式化输出函数&#xff0c;旨在替代传统的 std::cout 链式调用。它们基于 std::format 实现&#xff0c;支持类型安全的格式化字符串&#xff0c;语法更简洁&#xff0c;性能更优15。 功能特点&#xff1a; 直接输出到…...

高压直流输电MATLAB/simulink仿真模型+说明文档

1.模型简介 本仿真模型基于MATLAB/Simulink&#xff08;版本MATLAB 2018Ra&#xff09;软件。建议采用matlab2018 Ra及以上版本打开。&#xff08;若需要其他版本可联系代为转换&#xff09; 使用一个传输功率为1000MW&#xff08;500 kV&#xff0c;2 kA&#xff09;直流互连…...

第十四章-PHP与HTTP协议

第十四章-PHP与HTTP协议 一&#xff0c;HTTP 协议详解 HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;是互联网上应用最广泛的协议之一&#xff0c;用于客户端&#xff08;如浏览器&#xff09;与服务器之间的通信。它是 Web 技术的基石…...

【阿里云大模型高级工程师ACP学习笔记】2.6.用插件扩展答疑机器人的能力边界

一、学习目标 备考阿里云大模型高级工程师ACP认证,深入学习《2.6.用插件扩展答疑机器人的能力边界》这部分内容,主要期望达成以下目标: 理解智能体应用核心概念:理解智能体(Agent)应用的核心概念,包括其如何拓展大模型能力,突破传统答疑机器人局限。掌握构建Agent系统…...

用远程代理模式轻松实现远程服务调用,打开编程新大门

通过远程代理来实现一个简易的远程过程调用实例。带你打开新的大门。 Socket 远程代理服务案例 基于 Socket 的远程服务&#xff0c;我们需要完成以下步骤&#xff1a; 服务端实现&#xff1a;创建一个远程服务&#xff0c;通过 Socket 接受客户端请求并提供计算服务。 客户端…...

(001)Excel 快捷键

文章目录 时间 时间 当前日期&#xff1a;ctrl ; (分号)。当前时间&#xff1a;ctrl Shift ; (分号)。...

TMI投稿指南(二):投稿文章注意事项

文章结构&#xff1a; https://journals.ieeeauthorcenter.ieee.org/create-your-ieee-journal-article/create-the-text-of-your-article/structure-your-article/ 补充材料&#xff1a;准备补充材料 - IEEE 作者中心期刊 --- Prepare Supplementary Materials - IEEE Author…...

从困局到破局的AI+数据分析

从困局到破局的AI数据分析 困局&#xff1a;数据分析的四道高墙破局&#xff1a;AI赋能全流程数据分析远见&#xff1a;AI数据分析的革命性意义 数据是新时代的石油&#xff0c;人工智能是炼油厂。当两者强强联合&#xff0c;一场数据分析的革命正悄然发生。 多少次你面对Excel…...