信号signal编程测试

信号会打断系统调用,慎用,就是用的时候测一测。

下面是信号的基础测试

信号

信号(signal)机制是UNIX系统中最为古老的进程之间的通信机制。它用于在一个或多个进程之间传递异步信号。信号可以由各种异步事件产生,例如键盘中断等。Shell也可以使用信号将作业控制命令传递给它的子进程。
Linux系统中定义了一系列的信号,这些信号可以由内核产生,也可以由系统中的其他进程产生,只要这些进程有足够的权限。可以使用kill命令(kill -l)在机器上列出所有的信号,如下所示:

lkmao@ubuntu:~$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) 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()函数用于截取系统的信号,对此信号挂接用户自己的处理函数。其原型如下:

NAME
       signal - ANSI C signal handling

SYNOPSIS
       #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 = 2

sig_func:25 -- SIGINT

kill函数和raise函数

NAME
       kill - send signal to a process

SYNOPSIS
       #include <sys/types.h>
       #include <signal.h>

       int kill(pid_t pid, int sig);
NAME
       raise - send a signal to the caller

SYNOPSIS
       #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 = 2

sig_func:27 -- SIGINT count = 1
sig_func:17 -- signo = 2

sig_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

小结

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机毕业论文内容参考|基于三维建模和卷积神经网络的人脸转正的技术设计

文章目录 导文文章重点摘要前言绪论课题背景国内外现状与趋势课题内容相关技术与方法介绍技术分析技术设计人脸转正方法卷积神经网络的训练和优化数据预处理技术实现总结与展望本文总结导文 基于java开发汽车销售系统资料 文章重点 摘要 在实际应用中,人脸图像往往具有旋转、…

vue+elementui+nodejs校园高校餐厅点餐及订餐菜品推荐评价系统6927k

传统的销售模式&#xff0c;在实体店的紧跟式的销售模式&#xff0c;会给消费者一种不自由&#xff0c;被监视的感觉。餐厅点餐及推荐系统&#xff0c;紧跟数据时代的步伐&#xff0c;使用nodejs开发语言&#xff0c;配备MySQL数据库。扎根于实际问题所开发出来的一套系统。这个…

【C进阶】-- 字符串函数(1)

目录 0. 前言 1. 函数介绍 1.1 strlen 1.1.1主动改变\0的位置 ✅"strlen函数的返回类型是size_t - 无符号整型"✅ 当使用strlen函数但不引用头文件时&#xff0c;执行结果超出预料: 求字符串长度的方法&#x1f4a5; 1.计数器 2.递归 3.指针 - 指针 1.2 st…

项目集战略一致性

项目集战略一致性是识别项目集输出和成果&#xff0c;以便与组织的目标和目的保持一致的绩效领域。 本章内容包括&#xff1a; 1 项目集商业论证 2 项目集章程 3 项目集路线图 4 环境评估 5 项目集风险管理战略 项目集应与组织战略保持一致&#xff0c;并促进组织效益的实现。为…

粒子群算法(PSO)

理论&#xff1a; 粒子群优化算法&#xff08;PSO&#xff09;是一种智能优化算法&#xff0c;也是一种元启发式算法&#xff0c;最初是由Eberhart和Kennedy提出的&#xff0c;其模拟了鸟群捕食行为&#xff0c;通过一定的搜索策略&#xff0c;使得多个粒子在多维搜索空间中寻…

Java+Python+Paddle提取长文本文章中词频,用于Echart词云图数据

公司有个需求&#xff0c;就是需要提供给echart词云图的数据&#xff0c;放在以前我们的数据来源都是从产品那直接要&#xff0c;产品也是跑的别的接口&#xff0c;那怎么行呢&#xff0c;当然有自己的一套可以随便搞了&#xff0c;那么操作来了 Java package cn.iocoder.yud…

第十四届蓝桥杯大赛软件赛省赛(Java 大学A组)

蓝桥杯 2023年省赛真题 Java 大学A组 试题 A: 特殊日期  试题 B: 与或异或  试题 I: 高塔 把填空挂上跟大伙对对答案&#xff0c;然后 I \rm I I 题出的还行就先讲讲&#xff0c;剩下的最近有点忙&#xff0c;先放放。 试题 A: 特殊日期 本题总分&#xff1a;5 分 【问题描…

PMP课堂模拟题目及解析(第5期)

41. 项目的混凝土供应商通知项目经理&#xff0c;材料将比预定时间晚三个星期交付。项目经理更新了进度计划并通知项目团队。在这种情况下&#xff0c;哪种合同类型承担的风 险最小&#xff1f; A. 总价加激励费用合同。 B. 总价加经济价格调整合同。 C. 工料合同。 D. 固…

利用阿里云免费部署openai的Chatgpt国内直接用

背景 国内无法直接访问ChatGPT&#xff0c;一访问就显示 code 1020。而且最近OpenAI查的比较严格&#xff0c;开始大规模对亚洲地区开始封号&#xff0c;对于经常乱跳IP的、同一个ip一堆账号的、之前淘宝机刷账号的&#xff0c;账号被封的可能性极大。 那么有没有符合openai规定…

PLC与无线开关量测控终端之间Modbus通信实例

本方案是基于Modbus RTU协议下实现的1主多从自组网无线通信形式&#xff0c;主站为S7-1200 PLC&#xff0c;DTD433H作为从站。DTD433H具备输入和输出开关量信号功能&#xff0c;信号传输方向由用户原系统主从设备所实现的功能决定。方案中采用无线开关量信号测控终端DTD433H与欧…

NC – 靶向特定功能的神经元细胞类型治疗脑部疾病

神经元是大脑的主要功能单位。这些细胞中传递的信号——以电波的形式——导致所有思维、感觉、运动、记忆和情感。 塞达斯-西奈医学中心的研究人员利用计算机模型来弥合“试管”神经元数据和这些细胞在大脑中的功能之间的差距。他们的研究有助于开发靶向特定功能的神经元类型治…

迅为国产化RK3588开发平台16G大内存64G存储2路千兆以太网4G/5G通信

iTOP-3588开发板采用瑞芯微RK3588处理器&#xff0c;是全新一代AloT高端应用芯片采用8nmLP制程&#xff0c;搭载八核64位CPU(四核Cortex-A76四核Cortex-A55架构)集成MaliG610MP4四核GPU&#xff0c;内置AI加速器NPU&#xff0c;算力达6Tops&#xff0c;集成独立的8K视频硬件编码…

HTML-CSS学习笔记

day1-01.CSS的元素显示模式 元素的显示模式就是元素&#xff08;标签&#xff09;以什么方式进行展示&#xff0c;比如<div>自己占一行&#xff0c;<span>一行可以放多个。 HTML元素一般分为块元素和行内元素两种类型。 块元素 如果在p标签中放了div标签&#xff…

企业邮箱选购,需关注哪些重要因素?

企业邮箱选择考虑哪些问题&#xff1f;应该从企业邮箱安全、企业邮箱的稳定性、企业邮箱专业、方便迁移到新的企业邮箱、企业邮箱邮件的到达率、功能强大的企业邮箱、企业邮箱手机客户端设置等方面考虑。 1.企业邮箱安全 企业邮箱应考虑病毒防治能力。Zoho Mail企业邮箱从物理安…

【LeetCode困难】1263. 推箱子

「推箱子」是一款风靡全球的益智小游戏&#xff0c;玩家需要将箱子推到仓库中的目标位置。 游戏地图用大小为 m x n 的网格 grid 表示&#xff0c;其中每个元素可以是墙、地板或者是箱子。 现在你将作为玩家参与游戏&#xff0c;按规则将箱子 ‘B’ 移动到目标位置 ‘T’ &am…

创新指南|5大策略让创新业务扩张最大避免“增长痛苦”

公司在开发和孵化新业务计划方面进行了大量投资&#xff0c;但很少有公司遵循严格的途径来扩大新业务规模。虽然80%的公司声称构思和孵化新企业&#xff0c;但只有16%的公司成功扩大了规模。典型案例是百思买在许多失败倒闭的扩大新业务取得了成功。它经历了建立新业务所需的3个…

手残也不该敲的命令

Linux命令是一种很有趣且有用的东西&#xff0c;但在你不知道会带来什么后果的时候&#xff0c;它又会显得非常危险。所以&#xff0c;在输入某些命令前&#xff0c;请多多检查再敲回车。 rm –rf rm –rf是删除文件夹和里面附带内容的一种最快捷的方法&#xff0c;但是细微的…

深度学习03-卷积神经网络(CNN)

简介 CNN&#xff0c;即卷积神经网络&#xff08;Convolutional Neural Network&#xff09;&#xff0c;是一种常用于图像和视频处理的深度学习模型。与传统神经网络相比&#xff0c;CNN 有着更好的处理图像和序列数据的能力&#xff0c;因为它能够自动学习图像中的特征&…

安全防线再升级 | 中睿天下全流量安全分析系统重磅回归

随着信息化的加速&#xff0c;企业网络日趋完善。企业数字化的加速&#xff0c;让越来越多的关键业务运行在计算机网络基础之上&#xff0c;越来越多的重要信息通过网络传送&#xff0c;企业网络面临日益严重的安全威胁&#xff0c;这些安全威胁以窃取信息和收集情报为主&#…

中文润色神器-中文润色软件

中文写作润色软件 中文写作润色软件是一种基于自然语言处理技术和人工智能算法的工具&#xff0c;旨在提高中文文本的语言风格、表达能力和可读性。它可以自动检测文本中出现的语法、拼写、标点符号等语言问题&#xff0c;并给出相应的修正和修改建议。 中文写作润色软件的主…