信号(三)

1.信号发送函数

(1)alarm SIGALRM

          unsigned int alarm(unsigned int seconds);

          alarm函数,设置一个闹钟延迟发送SIGALRM信号(告诉Linux内核n秒中以后,发送SIGALRM信号);

(2)setitimer SIGALRM SIGVALRM SIGPROF

(3)abort SIGABRT

(4)kill命令 kill -ALRM `ps -aux | grep a.out | grep -v grep| awk '{ print $2}'`或者kill -14 pid或者kill -SIGALRM pid

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>




#define ERR_EXIT(m) \
    do \
    { \
        perror(m); \
        exit(EXIT_FAILURE); \
    }while(0)
    

void handler(int sig);

int main () {
    signal(SIGALRM, handler);
    alarm(1);
    for(;;) {
        pause();
        printf("pause return\n");
    }
        return 0;
}

void handler(int sig) {
    printf("recv a sig=%d\n", sig);
    alarm(1);
    //sleep(1);
}

递归调用alarm

2.可重入函数

(1)为了增强程序的稳定性,在信号处理函数中应使用可重入函数。

(2)所谓可重入函数是指一个可以被多个任务调用的过程,任务在调用时不必担心数据是否会出错。因为进程在收到信号后,就将跳转到信号处理函数去接着执行。如果信号处理函数中使用了不可重入函数,那么信号处理函数可能会修改原来进程中不应该被修改的数据,这样进程从信号处理函数中返回接着执行时,可能会出现不可预料的后果。不可重入函数在信号处理函数中被视为不安全函数。

(3)满足下列条件的函数多数是不可重入的:

    [1]使用静态数据结构,如getlogin(),gmtime(),getgrgid(),getgrnam(),getpwuid()以及getpwnam()等等;

    [2]函数实现时,调用了malloc()或者free()函数;

    [3]实现时使用了标准I/O函数

(4)man 7 signal可以查看那些函数是可重入和不可重入的

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>




#define ERR_EXIT(m) \
    do \
    { \
        perror(m); \
        exit(EXIT_FAILURE); \
    }while(0)
    

typedef struct {
        int a;
        int b;
} TEST;

TEST g_data;

void handler(int sig);

int main () {
    TEST zeros = {0, 0};
    TEST ones = {1, 1};

    signal(SIGALRM, handler);

    g_data = zeros;
    alarm(1);
    for(;;) {
        g_data = zeros;
        g_data = ones;
    }
        return 0;
}

void unsafe_fun() {
    printf("%d %d\n", g_data.a, g_data.b);
}

void handler(int sig) {
    unsafe_fun();
    alarm(1);
    //sleep(1);
}




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值