信号signal编程测试

2023-05-16

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

下面是信号的基础测试

信号

信号(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

小结

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

信号signal编程测试 的相关文章

随机推荐

  • C语言开发Linux下web服务器(支持GET/POST,SSL,目录显示等)

    这个主要是在CSAPP基础上做的 xff0c 添加了POST xff0c SSL xff0c 目录显示等功能 一 实现功能 xff1a 1 支持GET POST方法 2 支持SSL安全连接即HTTPS 3 支持CGI 4 基于IP地址和掩码
  • sklearn2pmml xgboost缺失值(missing)处理的坑

    sklearn2pmml xgboost缺失值 missing 处理的坑 今天同事在部署xgboost pmml模型时遇到了大坑 xff0c 线上spark预测和本地python预测结果怎么都不对应 xff0c 记录一下处理过程 看了下同事
  • adb导出手机应用到电脑

    简单说一下相关步骤 xff0c 以备不时之需 1 手机开启usb调试 2 Windows系统 Win 43 R打开命令行窗口 xff0c 输入adb devices xff0c 如果连接成功会出现机子的序列号 3 adb shell pm
  • Js作用域与作用域链详解

    一直对Js的作用域有点迷糊 xff0c 今天偶然读到Javascript权威指南 xff0c 立马被吸引住了 xff0c 写的真不错 我看的是第六版本 xff0c 相当的厚 xff0c 大概1000多页 xff0c Js博大精深 xff0c
  • windows10环境下tensorflow安装教程

    楼主最近一直忙着找工作 最近几个月一直all in java 好久没学机器学习 深度学习 前几天突然通知要提交论文中期了 于是赶紧打开电脑 结果发现之前安装的tensorflow居然登陆不上了 折腾了半天 搜过各种csdn博客 一直安装失败
  • 'gbk' codec can't encode character '\xa0'

    从网上抓了一些字节流 xff0c 想打印出来结果发生了一下错误 xff1a UnicodeEncodeError 39 gbk 39 codec can 39 t encode character 39 xbb 39 in position
  • 【Git记录学习】github创建项目以及本地使用(vscode)

    一 github创建空仓库 从github中创建空仓库 在执行完上一步操作后会返回这样的界面 xff0c 包括了一些基本的git操作以及HttpS SSH地址 生成一个readme md文档 xff08 步骤2 Set up下面有蓝色的超链
  • 关于DFT变换含义、公式和具体形式

    原文地址 xff1a http blog sina com cn s blog 7853c3910102v9wd html 这篇文章从实际工程应用的角度 xff0c 记录一下如何计算 xff0c 关于公式 变形和应用 维基百科上的 DFT公
  • 1602显示数字不稳定一直跳动(AD转换)

    程序如下所示 首先说明下 xff0c 此程序为AD转换芯片PCF8591采集电压数据 xff0c 然后送到1602显示 现象 xff1a 1602显示的数字一直频繁的跳动 xff0c 乱花眼 此现象不是一直出现的 xff0c 有时候会出现
  • C++11中的线程类

    前面介绍的线程是利用了POSIX线程库 xff0c 这是传统C C 43 43 程序员使用线程的方式 xff0c 而C 43 43 11提供了语言层面使用线程的方式 C 43 43 11新标准中引入了5个头文件来支持多线程编程 xff0c
  • 4.4.1内核编译

    内核源码下载地址 xff1a https mirrors edge kernel org pub linux kernel v4 x linux 4 4 1 tar gz 安装依赖包 xff1a 报错就装 cp boot config xx
  • fatal error: hugetlbfs.h: No such file or directory

    fatal error hugetlbfs h No such file or directory 解决办法 xff1a sudo apt get update sudo apt get install libhugetlbfs dev
  • WSL下 配置NFS-失败

    配置一个IP地址 xff1a sudo ip addr add 192 168 250 2 24 broadcast 192 168 250 255 dev eth2 sudo apt get install nfs kernel serv
  • OMT 对象模型、动态模型和功能模型

    对象模型描述系统中对象的静态结构 对象之间的关系 对象的属性 对象的操作 对象模型表示静态的 结构上的 系统的 数据 34 特征 对象模型为动态模型和功能模型提供了基本的框架 xff0c 对象模型用包含对象和类的对象图来表示 OMT的对象模
  • 关于epoll的调试的几个问题

    将今天调试的几个小问题点总结下 xff0c 后续遇到再添加 一 将总结的问题点放在最前面 1 epoll wait的maxevents参数 epoll wait的maxevents参数 xff0c 经过测试 xff0c maxevents的
  • poll函数测试

    一 基础知识 include lt poll h gt int poll struct pollfd fds nfds t nfds int timeout 其中参数fds指向一个结构体数组的第0个元素的指针 xff0c 每个数组元素都是一
  • IPC:匿名管道和命名管道

    一 管道初级测试 写两个小程序 xff0c 一个负责向管道发数据 xff0c 一个从管道接收数据 xff1b pipe cpp include lt iostream gt using namespace std int main cout
  • IPC:system V消息队列

    ftok函数 ftok convert a pathname and a project identifier to a System V IPC key SYNOPSIS include lt sys types h gt include
  • IPC:system V 信号量和共享内存

    信号量相关知识 结构体 union semun int val Value for SETVAL struct semid ds buf Buffer for IPC STAT IPC SET unsigned short array Ar
  • 信号signal编程测试

    信号会打断系统调用 xff0c 慎用 xff0c 就是用的时候测一测 下面是信号的基础测试 信号 信号 xff08 signal xff09 机制是UNIX系统中最为古老的进程之间的通信机制 它用于在一个或多个进程之间传递异步信号 信号可以