11_alarm()和可重入函数

pause()函数
   将进程置为可中断睡眠状态。然后它调用内核函数schedule(),使linux进程调度器找到另一个进程来运行。
   pause使调用者进程挂起,直到一个信号被捕获
NAME
       alarm - set an alarm clock for delivery of a signal

SYNOPSIS
       #include <unistd.h>

       unsigned int alarm(unsigned int seconds);

DESCRIPTION
       alarm()  arranges for a SIGALRM signal to be delivered to the calling process in
       seconds seconds.

       If seconds is zero, any pending alarm is canceled.

       In any event any previously set alarm() is canceled.

RETURN VALUE
       alarm() returns the number of seconds remaining until any  previously  scheduled
       alarm  was  due  to  be  delivered, or zero if there was no previously scheduled
       alarm.
/*
    信号处理函数遇上可重入和不可重入函数
    可重入函数概念
    1、为了增强程序的稳定性,在信号处理函数中应使用可重入函数。 
    2、所谓可重入函数是指一个可以被多个任务调用的过程,任务在调用时
      不必担心数据是否会出错。因为进程在收到信号后,就将跳转到信号处理
      函数去接着执行。如果信号处理函数中使用了不可重入函数,那么信号
      处理函数可能会修改原来进程中不应该被修改的数据,这样进程从信号
      处理函数中返回接着执行时,可能会出现不可预料的后果。不可再入函数
      在信号处理函数中被视为不安全函数。
  3、满足下列条件的函数多数是不可重入的:
  (1)使用静态的数据结构,如getlogin(),gmtime(),getgrgid(),getgrnam(),
            getpwuid()以及getpwnam()等等;
  (2)函数实现时,调用了malloc()或者free()函数;
  (3)实现时使用了标准I/O函数的
*/
/*
    alarm函数,设置一个闹钟延迟发送信号
    告诉linux内核n秒中以后,发送SIGALRM信号;

    使用命令发送信号:
        hzmct@U-64:~$ kill -14  pid
        hzmct@U-64:~$ kill -ALRM  pid
        hzmct@U-64:~$ kill -SIGALRM  pid
*/

//使用闹钟周期性发送SIGALRM信号
#if 1
void  myhandle(int num)
{
    printf("recv signal id num : %d \n", num);
    //kill -alram ` ps -aux | grep 01aram | grep -v vi | awk '{print $2}' ` 
    alarm(1);//信号调用函数调用alarm(),可以周期1s发送此信号
}
void test()
{
    printf("main ....begin\n");
    //注册SIGALRM 信号处理函数
    if (signal(SIGALRM, myhandle) == SIG_ERR)
    {
        perror("func signal err\n");
        return ;
    } 
    //间接递归
    //myhandle----->alarm=====>myhandle
    alarm(1);//延迟1s发送一个信号SIGALRM

    while(1) 
    {
        pause();
        printf("pause return\n");
    }
}

#endif
/*
在信号处理函数中,尽量不使用全局变量和静态变量的函数。
    特别是这个变量在程序中随时读写。
    可能会出现age30 num40的现象
*/
#if 0
typedef struct _Teacher
{
    int age;
    int num;    
}Teacher;

Teacher g_t;//全局变量

void printfGlobTeacher()
{
    printf("g_t.age:%d \n", g_t.age);
    printf("g_t.num:%d \n", g_t.num);
    //p = malloc(100);
}

void  myhandle(int num)
{
    printf("recv signal id num : %d \n", num);
    printfGlobTeacher();
    alarm(1);
}

void test()
{
    Teacher t1, t2;
    t1.age = 30;
    t1.num = 30;
    t2.age = 40;
    t2.num = 40;
    printf("main ....begin\n");
    //注册信号处理函数
    if (signal(SIGALRM, myhandle) == SIG_ERR)
    {
        perror("func signal err\n");
        return ;
    } 
    alarm(1);
    //不断的修改全局变量的值
    while(1) 
    {
        g_t = t1;
        g_t = t2;
    }
}
#endif

猜你喜欢

转载自blog.csdn.net/WUZHU2017/article/details/81878401
今日推荐