信号signal编程测试
信号会打断系统调用,慎用,就是用的时候测一测。
下面是信号的基础测试
信号
信号(signal)机制是UNIX系统中最为古老的进程之间的通信机制。它用于在一个或多个进程之间传递异步信号。信号可以由各种异步事件产生,例如键盘中断等。Shell也可以使用信号将作业控制命令传递给它的子进程。
Linux系统中定义了一系列的信号,这些信号可以由内核产生,也可以由系统中的其他进程产生,只要这些进程有足够的权限。可以使用kill命令(kill -l)在机器上列出所有的信号,如下所示:
lkmao@ubuntu:~$ kill -l1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
lkmao@ubuntu:~$
进程可以屏蔽掉大多数的信号,除了SIGSTOP和SIGKILL。SIGSTOP信号使一个正在运行的进程暂停,而信号SIGKILL则使正在运行的进程退出。进程可以选择系统的默认方式处理信号,也可以选择自己的方式处理产生的信号。信号之间不存在相对的优先权,系统也无法处理同时产生的多个同种的信号,也就是说,进程不能分辨它收到的是1个或者是42个SIGCONT信号。
SIGCONT:此作业控制信号送给需要继续运行的处于停止状态的进程。如果接收到此信号的进程处于停止状态,则操作系统的默认动作是使该停止的进程继续运行,否则默认动作是忽略此信号。
SIGEMT:指示一个实现定义的硬件故障。
SIGFPE:此信号表示一个算术运算异常,例如除以0,浮点溢出等。
SIGHUP:如果终端界面检测到一个连接断开,则将此信号送给与该终端相关的进程。 SIGILL:此信号指示进程已执行一条非法硬件指令。
SIGINT:当用户按中断键(一般采用Delete或Ctrl+C)时,终端驱动程序产生这个信号并将信号送给前台进程组中的每一个进程。当一个进程在运行时失控,特别是它正在屏幕上产生大量不需要的输出时,常用此信号终止它。
SIGIO:此信号指示一个异步IO事件。
SIGIOT:这指示一个实现定义的硬件故障。
SIGPIPE:如果在读进程时已终止写管道,则产生此信号。
SIGQUIT:当用户在终端上按退出键(一般采用Ctrl+C)时,产生此信号,并送至前台进程组中的所有进程。
SIGSEGV:指示进程进行了一次无效的存储访问。
SIGSTOP:这是一个作业控制信号,它停止一个进程。
SIGSYS:指示一个无效的系统调用。由于某种未知原因,某个进程执行了一条系统调用命令,但是调用命令所用的参数无效。
SIGTERM:这是由kill命令发送的系统默认终止信号。
SIGTRAP:指示一个实现定义的硬件故障。
SIGTSTP:交互停止信号,当用户在终端上按挂起键(一般采用Ctrl+Z)时,终端驱动程序产生此信号。
SIGTTIN:当一个后台进程组进程试图读其控制终端时,终端驱动程序产生此信号。 SIGTTOU:当一个后台进程组进程试图写其控制终端时产生此信号。
SIGURG:此信号通知进程已经发生一个紧急情况。在网络连接上,接到非规定波特率的数据时,此信号可选择地产生。
SIGUSR1:这是一个用户定义的信号,可用于应用程序。
SIGUSR2:这是一个用户定义的信号,可用于应用程序。
信号截取函数signal()
signal()函数用于截取系统的信号,对此信号挂接用户自己的处理函数。其原型如下:
NAMEsignal - ANSI C signal handlingSYNOPSIS#include <signal.h>typedef void (*sighandler_t)(int);sighandler_t signal(int signum, sighandler_t handler);
signal()函数的原型说明此函数要求两个参数,返回一个函数指针,而该指针所指向的函数无返回值(void)。第1个参数signo是一个整型数,第2个参数是函数指针,它所指向的函数需要一个整型参数,无返回值。用一般语言来描述就是要向信号处理程序传送一个整型参数,而它却无返回值。当调用signal设置信号处理程序时,第2个参数是指向该函数(也就是信号处理程序)的指针。signal的返回值指向以前信号处理程序的指针。
如下代码截取了系统的信号SIGSTOP和SIGKILL,用命令kill杀死其是不可能的。
测试一:尝试截获信号SIGSTOP和SIGKILL
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>#define DEBUG_INFO(format, ...) printf("%s:%d -- " format "\n", __func__, __LINE__,##__VA_ARGS__)typedef void (*sighandler)(int signo);static void sig_kill(int signo){DEBUG_INFO("signo = %d\n", signo);
}static void sig_stop(int signo){DEBUG_INFO("signo = %d\n", signo);
}int main(int argc, char **argv){sighandler ret;ret = signal(SIGKILL, sig_kill);if(ret == SIG_ERR){perror("signal sig_kill");DEBUG_INFO("signal SIGKILL error");//exit(-1);}ret = signal(SIGSTOP, sig_stop);if(ret == SIG_ERR){perror("signal sig_stop");//exit(-1);DEBUG_INFO("signal SIGSTOP error");}for(;;){sleep(1);}return 0;
}
执行结果:
signal sig_kill: Invalid argument
main:28 -- signal SIGKILL error
signal sig_stop: Invalid argument
main:35 -- signal SIGSTOP error
结论:这根本截获不了啊。
测试二:捕获SIGINT,捕获成功以后,将SIGINT信号设置为默认处理方式
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>#define DEBUG_INFO(format, ...) printf("%s:%d -- " format "\n", __func__, __LINE__,##__VA_ARGS__)typedef void (*sighandler)(int signo);static void sig_func(int signo){DEBUG_INFO("signo = %d\n", signo);switch(signo) {case SIGKILL:DEBUG_INFO("SIGKILL");break;case SIGSTOP:DEBUG_INFO("SIGSTOP");break;case SIGINT:DEBUG_INFO("SIGINT");signal(SIGINT, SIG_DFL);default:break;}
}
int main(int argc, char **argv){sighandler ret;ret = signal(SIGKILL, sig_func);if(ret == SIG_ERR){perror("signal sig_kill");DEBUG_INFO("signal SIGKILL error");//exit(-1);}ret = signal(SIGSTOP, sig_func);if(ret == SIG_ERR){perror("signal sig_stop");//exit(-1);DEBUG_INFO("signal SIGSTOP error");}ret = signal(SIGINT, sig_func);if(ret == SIG_ERR){perror("signal sig_stop");//exit(-1);DEBUG_INFO("signal SIGSTOP error");}for(;;){sleep(1);}return 0;
}
测试结果:按两次CTRL+C,第一次进入sig_func函数,第二次退出程序。
signal sig_kill: Invalid argument
main:37 -- signal SIGKILL error
signal sig_stop: Invalid argument
main:44 -- signal SIGSTOP error
^Csig_func:16 -- signo = 2sig_func:25 -- SIGINT
kill函数和raise函数
NAMEkill - send signal to a processSYNOPSIS#include <sys/types.h>#include <signal.h>int kill(pid_t pid, int sig);
NAMEraise - send a signal to the callerSYNOPSIS#include <signal.h>int raise(int sig);
测试三:kill函数和raise函数发送信号
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>#define DEBUG_INFO(format, ...) printf("%s:%d -- " format "\n", __func__, __LINE__,##__VA_ARGS__)typedef void (*sighandler)(int signo);static void sig_func(int signo){static int count = 0;DEBUG_INFO("signo = %d\n", signo);switch(signo) {case SIGKILL:DEBUG_INFO("SIGKILL");break;case SIGSTOP:DEBUG_INFO("SIGSTOP");break;case SIGINT:count++;DEBUG_INFO("SIGINT count = %d",count);if(count == 2){signal(SIGINT, SIG_DFL);}default:break;}
}
int main(int argc, char **argv){sighandler ret;ret = signal(SIGKILL, sig_func);if(ret == SIG_ERR){perror("signal sig_kill");DEBUG_INFO("signal SIGKILL error");//exit(-1);}ret = signal(SIGSTOP, sig_func);if(ret == SIG_ERR){perror("signal sig_stop");//exit(-1);DEBUG_INFO("signal SIGSTOP error");}ret = signal(SIGINT, sig_func);if(ret == SIG_ERR){perror("signal sig_stop");//exit(-1);DEBUG_INFO("signal SIGSTOP error");}raise(SIGINT);kill(getpid(),SIGINT);for(;;){sleep(1);}return 0;
}
测试结果:raise产生一次SIGINT信号,kill产生一次SIGINT信号,此时计数值count变成2,信号处理函数恢复默认值,最后CTRL+C退出进程。
signal sig_kill: Invalid argument
main:43 -- signal SIGKILL error
signal sig_stop: Invalid argument
main:50 -- signal SIGSTOP error
sig_func:17 -- signo = 2sig_func:27 -- SIGINT count = 1
sig_func:17 -- signo = 2sig_func:27 -- SIGINT count = 2
^C
SIGCHLD信号
测试程序:子进程退出时,会自动向父进程发送信号
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>#define DEBUG_INFO(format, ...) printf("%s:%d -- " format "\n", __func__, __LINE__,##__VA_ARGS__)typedef void (*sighandler)(int signo);static void sig_func(int signo){static int count = 0;//DEBUG_INFO("signo = %d\n", signo);switch(signo) {case SIGKILL:DEBUG_INFO("SIGKILL");break;case SIGSTOP:DEBUG_INFO("SIGSTOP");break;case SIGINT:count++;DEBUG_INFO("SIGINT count = %d",count);if(count == 2){signal(SIGINT, SIG_DFL);}break;case SIGCHLD:DEBUG_INFO("%u get a SIGCHLD signal",getppid());break; default:DEBUG_INFO("unknow signo = %d",signo);break;}
}
int main(int argc, char **argv){sighandler ret;ret = signal(SIGCHLD, sig_func);if(ret == SIG_ERR){perror("signal sig_kill");DEBUG_INFO("signal SIGKILL error");//exit(-1);}pid_t pid = fork();if(pid == 0){DEBUG_INFO("child running %u",getpid());DEBUG_INFO("send a SIGCHLD to %u",getppid());exit(0);}for(;;){sleep(1);}return 0;
}
执行结果:
main:54 -- child running 109007
main:55 -- send a SIGCHLD to 109006
sig_func:36 --
SIGABRT信号测试
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>#define DEBUG_INFO(format, ...) printf("%s:%d -- " format "\n", __func__, __LINE__,##__VA_ARGS__)typedef void (*sighandler)(int signo);static void sig_func(int signo){static int count = 0;switch(signo) {case SIGABRT:break;case SIGKILL:DEBUG_INFO("SIGKILL");break;case SIGSTOP:DEBUG_INFO("SIGSTOP");break;case SIGINT:count++;DEBUG_INFO("SIGINT count = %d",count);if(count == 2){signal(SIGINT, SIG_DFL);}break;case SIGCHLD:DEBUG_INFO("%u get a SIGCHLD signal",getppid());break; default:DEBUG_INFO("unknow signo = %d",signo);break;}
}
int main(int argc, char **argv){sighandler ret;ret = signal(SIGABRT, sig_func);if(ret == SIG_ERR){perror("signal");exit(-1);}DEBUG_INFO("send a SIGABRT signal by abort()");abort();sleep(1);return 0;
}
测试结果:
main:52 -- send a SIGABRT signal by abort()
./test.sh: 行 10: 111335 已放弃 (核心已转储) ./_build_test_cpp_test/signal
SIGCONT信号测试:实验中,父进程先睡眠,子进程向父进程发送SIGCONT信号,父进程退出睡眠,继续执行,然后退出程序。子进程变成孤儿进程,最后由进程1接管
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>#define DEBUG_INFO(format, ...) printf("%s:%d -- " format "\n", __func__, __LINE__,##__VA_ARGS__)typedef void (*sighandler)(int signo);static void sig_func(int signo){static int count = 0;switch(signo) {case SIGABRT:break;case SIGKILL:DEBUG_INFO("SIGKILL");break;case SIGSTOP:DEBUG_INFO("SIGSTOP");break;case SIGINT:count++;DEBUG_INFO("SIGINT count = %d",count);if(count == 2){signal(SIGINT, SIG_DFL);}break;case SIGCHLD:DEBUG_INFO("%u get a SIGCHLD signal",getppid());break; case SIGCONT:DEBUG_INFO("SIGCONT");break;default:DEBUG_INFO("unknow signo = %d",signo);break;}
}
int main(int argc, char **argv){sighandler ret;ret = signal(SIGCONT, sig_func);if(ret == SIG_ERR){perror("signal");exit(-1);}if(fork() == 0){DEBUG_INFO("%u send a SIGCONT signal",getppid());DEBUG_INFO("my parent is %u",getppid());kill(getppid(),SIGCONT);sleep(500);DEBUG_INFO("my parent is %u",getppid());DEBUG_INFO("bye bye");abort();}sleep(100);DEBUG_INFO("parent sleep is interrupt by signal SIGCONT");return 0;
}
执行结果:符合推到
main:58 -- 116350 send a SIGCONT signal
main:59 -- my parent is 116350
sig_func:41 -- SIGCONT
main:67 -- parent sleep is interrupt by signal SIGCONT
lkmao@ubuntu:/big/csi_driver/rty/01$ main:62 -- my parent is 1
main:63 -- bye bye
最后通过进程名字终止子进程的睡眠,它继续运行后,自行退出。
killall -SIGCONT signal
SIGHUP信号
问:如何产生一个SIGHUP信号
可以通过以下几种方式产生SIGHUP信号:
1. 在终端中使用kill命令,指定进程ID和信号类型:
```
kill -SIGHUP <进程ID>
```
2. 在终端中使用kill命令,指定进程名称和信号类型:
```
killall -SIGHUP <进程名称>
```3. 在程序中使用kill函数,指定进程ID和信号类型:
```c
kill(<进程ID>, SIGHUP);
```
4. 在程序中使用raise函数,产生当前进程的SIGHUP信号:
```c
raise(SIGHUP);
```
在什么情况下需要发送一个SIGHUP信号
SIGHUP信号通常用于重新加载配置文件或重新启动进程。以下是一些需要发送SIGHUP信号的情况:
1. 当进程的配置文件发生更改时,可以发送SIGHUP信号以重新加载配置文件。
2. 当进程需要重新启动时,可以发送SIGHUP信号以通知进程重新启动。
3. 当需要重新初始化进程时,可以发送SIGHUP信号以重新初始化进程。
4. 当需要重新读取进程的日志文件时,可以发送SIGHUP信号以重新打开日志文件。
5. 当需要重新加载进程的插件或模块时,可以发送SIGHUP信号以重新加载插件或模块。
测试代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>#define DEBUG_INFO(format, ...) printf("%s:%d -- " format "\n", __func__, __LINE__,##__VA_ARGS__)typedef void (*sighandler)(int signo);static void sig_func(int signo){static int count = 0;switch(signo) {case SIGABRT:break;case SIGKILL:DEBUG_INFO("SIGKILL");break;case SIGSTOP:DEBUG_INFO("SIGSTOP");break;case SIGINT:count++;DEBUG_INFO("SIGINT count = %d",count);if(count == 2){signal(SIGINT, SIG_DFL);}break;case SIGCHLD:DEBUG_INFO("%u get a SIGCHLD signal",getppid());break; case SIGCONT:DEBUG_INFO("SIGCONT %u",getppid());break;case SIGHUP:DEBUG_INFO("SIGHUP = %u",getpid());break;case SIGSYS:DEBUG_INFO("SIGSYS");break;case SIGTTOU:DEBUG_INFO("SIGTTOU");break;default:DEBUG_INFO("unknow signo = %d",signo);break;}
}
int main(int argc, char **argv){sighandler ret;ret = signal(SIGHUP,sig_func);if(ret == SIG_ERR){perror("signal");exit(-1);}DEBUG_INFO("pid = %u,ppid = %u",getpid(),getppid());if(fork() == 0){DEBUG_INFO("child %u",getpid());sleep(100);DEBUG_INFO("child %u",getpid());}sleep(100);DEBUG_INFO("parent sleep is interrupt by a signal");return 0;
}
测试结果:结果证明
1 SIGHUP信号可以被捕获
2 SIGHUP信号可以打断sleep睡眠。
3 父进程和子进程都收到了信号
SIGUSR1和SIGUSR2
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>#define DEBUG_INFO(format, ...) printf("%s:%d -- " format "\n", __func__, __LINE__,##__VA_ARGS__)typedef void (*sighandler)(int signo);static void sig_func(int signo){static int count = 0;switch(signo) {case SIGABRT:break;case SIGKILL:DEBUG_INFO("SIGKILL");break;case SIGSTOP:DEBUG_INFO("SIGSTOP");break;case SIGINT:count++;DEBUG_INFO("SIGINT count = %d",count);if(count == 2){signal(SIGINT, SIG_DFL);}break;case SIGCHLD:DEBUG_INFO("%u get a SIGCHLD signal",getppid());break; case SIGCONT:DEBUG_INFO("SIGCONT %u",getppid());break;case SIGHUP:DEBUG_INFO("SIGHUP = %u",getpid());break;case SIGSYS:DEBUG_INFO("SIGSYS");break;case SIGTTOU:DEBUG_INFO("SIGTTOU");break;case SIGUSR1:DEBUG_INFO("SIGUSR1 = %u",getpid());break;case SIGUSR2:DEBUG_INFO("SIGUSR2 = %u",getpid());break;default:DEBUG_INFO("unknow signo = %d",signo);break;}
}
int main(int argc, char **argv){sighandler ret;ret = signal(SIGHUP,sig_func);if(ret == SIG_ERR){perror("signal");exit(-1);}ret = signal(SIGUSR1,sig_func);if(ret == SIG_ERR){perror("signal");exit(-1);}ret = signal(SIGUSR2,sig_func);if(ret == SIG_ERR){perror("signal");exit(-1);}DEBUG_INFO("pid = %u,ppid = %u",getpid(),getppid());if(fork() == 0){DEBUG_INFO("child %u",getpid());kill(getppid(), SIGUSR1);kill(getpid(), SIGUSR2);sleep(100);DEBUG_INFO("child %u",getpid());}for(int i = 0; i < 10;i++){sleep(100);DEBUG_INFO("parent sleep is interrupt by a signal");}return 0;
}
执行结果:
main:80 -- pid = 126176,ppid = 126084
main:82 -- child 126177
sig_func:56 -- SIGUSR2 = 126177
sig_func:53 -- SIGUSR1 = 126176
main:92 -- parent sleep is interrupt by a signal
小结
相关文章:

信号signal编程测试
信号会打断系统调用,慎用,就是用的时候测一测。 下面是信号的基础测试 信号 信号(signal)机制是UNIX系统中最为古老的进程之间的通信机制。它用于在一个或多个进程之间传递异步信号。信号可以由各种异步事件产生,例如…...

Linux学习记录——이십삼 进程信号(2)
文章目录 1、可重入函数2、volatile关键字3、如何理解编译器的优化4、SIGCHLD信号 1、可重入函数 两个执行流都执行一个函数时,这个函数就被重入了。比如同一个函数insert,在main中执行时,这个进程时间片到了,嵌入了内核…...

Revit中如何创建曲面嵌板及一键成板
一、Revit中如何创建曲面嵌板 在我们的绘图过程中可能会遇见一些曲面形状,而我们的常规嵌板没办法满足我们绘制的要求,我们今天学习如何在revit中绘制曲面嵌板。 1.新建“自适应公制常规模型”族,创建4个点图元并为其使用自适应。 2.在相同的…...

STM32F4_DHT11数字温湿度传感器
目录 前言 1. DHT11简介 2. DHT11数据结构 3. DHT11的传输时序 3.1 DHT11开始发送数据流程 3.2 主机复位信号和DHT11响应信号 3.3 数字 “0” 信号表示方法 3.4 数字 “1” 信号表示方法 4. 硬件分析 5. 实验程序详解 5.1 main.c 5.2 DHT11.c 5.3 DHT11.h 前言 DH…...

WiFi(Wireless Fidelity)基础(十一)
目录 一、基本介绍(Introduction) 二、进化发展(Evolution) 三、PHY帧((PHY Frame ) 四、MAC帧(MAC Frame ) 五、协议(Protocol) 六、安全&#x…...

操作系统—— 精髓与设计原理--期末复习
一、计算机系统概述 1、基本构成 计算机有四个主要的结构化部件: ①处理器(Processor):控制计算机的操作,执行数据处理功能。当只有一个处理器时,它通常指中央处理器(CPU) ②内存…...

每天一道算法练习题--Day21 第一章 --算法专题 --- ----------位运算
我这里总结了几道位运算的题目分享给大家,分别是 136 和 137, 260 和 645, 总共加起来四道题。 四道题全部都是位运算的套路,如果你想练习位运算的话,不要错过哦~~ 前菜 开始之前我们先了解下…...

D1. LuoTianyi and the Floating Islands (Easy Version)(树形dp)
Problem - D1 - Codeforces 这是问题的简化版本。唯一的区别在于在该版本中k≤min(n,3)。只有在两个版本的问题都解决后,才能进行黑客攻击。 琴音和漂浮的岛屿。 洛天依现在生活在一个有n个漂浮岛屿的世界里。这些漂浮岛屿由n−1个无向航线连接,任意两个…...
rk3588移植ubuntu server
ubuntu server 18.04 arm版本. 1、使用qemu运行 安装qemu-system-aarch64 sudo apt install -y qemu-system-arm 2、下载ubuntu server Index of /releases/18.04.3 3、创建虚拟磁盘 qemu-img create ubuntuimg.img 40G 4、创建虚拟机 弹出界面,直接回车选…...
如何更好地刷力扣
之前刷力扣是一口气看很多题目,打算时不时看一会题解,逐渐熟悉套路,争取背过,最后就可以写出来了。我个人是背知识比较喜欢这种方法,但后来发现根本不适用 算法题本身就比较复杂,不经过实际写代码中的思考…...
上采样和下采样
首先,谈谈不平衡数据集。不平衡数据集指的是训练数据中不同类别的样本数量差别较大的情况。在这种情况下,模型容易出现偏差,导致模型对数量较少的类别预测效果不佳。 为了解决这个问题,可以使用上采样和下采样等方法来调整数据集…...
小猪,信息论与我们的生活
前言 动态规划是大家都熟悉与陌生的知识,非常灵活多变,我自己也不敢说自己掌握了,今天给大家介绍一道题,不仅局限于动态规划做题,还会上升到信息论,乃至于启发自己认知世界的角度 因为比较难,本…...

【鸿蒙应用ArkTS开发系列】- http网络库使用讲解和封装
目录 前言http网络库组件介绍http网络库封装创建Har Module创建RequestOption 配置类创建HttpCore核心类创建HttpManager核心类对外组件导出添加网络权限 http网络库依赖和使用依赖http网络库(httpLibrary)使用http网络库(httpLibrary&#x…...

【Java零基础入门篇】第 ⑥ 期 - 异常处理
博主:命运之光 专栏:Java零基础入门 学习目标 掌握异常的概念,Java中的常见异常类; 掌握Java中如何捕获和处理异常; 掌握自定义异常类及其使用; 目录 异常概述 异常体系 常见的异常 Java的异常处理机制…...
计算职工工资
目录 问题描述 程序设计 问题描述 【问题描述】 给定N个职员的信息,包括姓名、基本工资、浮动工资和支出,要求编写程序顺序输出每位职员的姓名和实发工资(实发工资=基本工资+浮动工资-支出)。 【输入形式】 输入在一行中给出正整数N。随后N行,每行给出一位职员的信息,…...

2019年上半年软件设计师下午试题
试题四(共 15 分) 阅读下列说明和 C 代码,回答问题 1 至 3,将解答写在答题纸的对应栏内 【说明】 n 皇后问题描述为:在一个 n*n 的棋盘上摆放 n 个皇后,要求任意两个皇后不能冲突, 即任意两个皇后不在同一行、同一列或者同一斜…...

IS200TPROH1BCB用于工业应用和电力分配等。高压型隔离开关用于变电站
IS200TPROH1BCB用于工业应用和电力分配等。高压型隔离开关用于变电站 什么是隔离器,它与断路器有何不同 什么是隔离器,为什么要使用隔离器 隔离器是一种开关装置,它可以手动或自动操作,隔离一部分电能。隔离器可用于在无负载情…...

【MySql】数据库 select 进阶
数据库 数据库表的设计ER 关系图三大范式 聚合函数与分组查询聚合函数 (count、sum、avg、max、min)分组查询 group by fields....having....(条件) 多表联查内连接外连接(左连接,右连接)自连接子查询合并查询 UNION 数据库表的设计 ER 关系…...

CVPR 2023 | VoxelNeXt实现全稀疏3D检测跟踪,还能结合Seg Anything
在本文中,研究者提出了一个完全稀疏且以体素为基础的3D物体检测和跟踪框架VoxelNeXt。它采用简单的技术,运行快速,没有太多额外的成本,并且可以在没有NMS后处理的情况下以优雅的方式工作。VoxelNeXt在大规模数据集nuScenes、Waymo…...

本地使用3台centos7虚拟机搭建K8S集群教程
第一步 准备3台centos7虚拟机 3台虚拟机与主机的网络模式都是桥接的模式,也就是他们都是一台独立的“主机” (1)kebe-master的配置 虚拟机配置: 网络配置: (2)kebe-node1的配置 虚拟机配…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...

1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10pip3.10) 一:前言二:安装编译依赖二:安装Python3.10三:安装PIP3.10四:安装Paddlepaddle基础框架4.1…...

leetcode73-矩阵置零
leetcode 73 思路 记录 0 元素的位置:遍历整个矩阵,找出所有值为 0 的元素,并将它们的坐标记录在数组zeroPosition中置零操作:遍历记录的所有 0 元素位置,将每个位置对应的行和列的所有元素置为 0 具体步骤 初始化…...