信号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的配置 虚拟机配…...

NVIDIA CUDA驱动安装
1 引言 因为笔记本电脑上运行Milvus图像检索代码,需要安装CUDA驱动。电脑显卡型号是NVIDIA GeForce GTX 1050 Ti Mobile, 操作系统是Ubuntu 20.04,内核版本为Linux 5.15.0-72-generic。 2 CUDA驱动测试 参考网上的资料:https://blog.csdn.…...

python 从excel中获取需要执行的用例
classmethod def get_excel_data(cls, excel_name, sheet_name, case_numNone):"""读取excel文件的方法:param excel_name: 文件名称:param sheet_name: sheet页的名称:param case_name: 执行的case名称:return:"""def get_row_data(table, row)…...

Web3中文|乱花渐欲meme人眼,BRC-20总市值逼近10亿美元
现在的Web3加密市场,用“乱花渐欲meme人眼”来形容再合适不过了。 何为meme? “meme”这个词大概很多人都不知道如何正确发音,并且一看到它就会和狗狗币Dogecoin等联系在一起。那它究竟从何而来呢? Meme:[mi:m]&#x…...

盖雅案例入选「首届人力资源服务国际贸易交流合作大会20项创新经验」
近日,首届人力资源服务国际贸易交流合作大会顺利召开。为激励企业在人力资源服务贸易领域不断创新,加快培育对外贸易新业态、新模式,形成人力资源服务领域国际竞争新优势,大会评选出了「首届人力资源服务国际贸易交流合作大会20项…...

[论文笔记]SimMIM:a Simple Framework for Masked Image Modeling
文章地址:https://arxiv.org/abs/2111.09886 代码地址:https://github.com/microsoft/SimMIM 文章目录 摘要文章思路创新点文章框架Masking strategyPrediction headPrediction targetEvaluation protocols 性能实验实验设置Mask 策略预测头目标分辨率预…...

mysql从零开始(4)----索引/视图/范式
接上文 mysql从零开始(3) 索引 索引是在数据库表的字段上添加的,是为了提高查询效率存在的一种机制。一张表的一个字段可以添加一个索引,也可以多个字段联合起来添加索引。索引相当于一本书的目录,是为了缩小扫描范围…...

Flutter框架:从入门到实战,构建跨平台移动应用的全流程解析
第一章:Flutter框架介绍 Flutter框架是由Google推出的一款跨平台移动应用开发框架。相比其他跨平台框架,Flutter具有更高的性能和更好的用户体验。本章将介绍Flutter框架的概念、特点以及与其他跨平台框架的比较,以及Flutter开发环境的搭建和…...

Spring AOP+注解方式实现系统日志记录
一、前言 在上篇文章中,我们使用了AOP思想实现日志记录的功能,代码中采用了指定连接点方式(Pointcut(“execution(* com.nowcoder.community.controller..(…))”)),指定后不需要在进行任何操作就可以记录日志了&…...

OpenGL 4.0的Tessellation Shader(细分曲面着色器)
细分曲面着色器(Tessellation Shader)处于顶点着色器阶段的下一个阶段,我们可以看以下链接的OpenGL渲染流水线的图:Rendering Pipeline Overview。它是由ATI在2001年率先设计出来的。 目录 细分曲面着色器细分曲面Patch细分曲面控…...

项目经理如何及时掌控项目进度?
延迟是指超出计划的时间,而无法掌控则意味着管理者对实际情况一无所知。 为了解决这些问题,我们需要建立好的制度和沟通机制。例如使用项目管理软件来跟踪进度、定期开会并避免沟通障碍等。 管理者可以建立相关制度: 1、建立进度记录制度。…...