进程的挂起以及可重入函数

  1. 相关接口
    这里写图片描述
        pause 函数用于将进程挂起. 如果信号的处理动作是终止进程, 则进程终止, pause 函数没有返回值; 如果信号的处理动作是忽略, 则进程被挂起, pause函数不返回, 如果信号的处理动作是捕捉, 则调用信号处理动作之后pause 返回 -1.
  2. 来看一段代码
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>

void sig_alarm(int seconds)
{

}
int mysleep(int seconds)
{

    struct sigaction act;
    struct sigaction oact;
    int unslept = 0;
    act.sa_handler = sig_alarm;
    act.sa_flags = 0;
    sigemptyset(&act.sa_mask);
    sigemptyset(&oact.sa_mask);
    sigaction(SIGALRM, &act, &oact);
    alarm(seconds);
    pause();
    unslept = alarm(0);
    sigaction(SIGALRM, &oact, NULL);
}
int main()
{
    while(1)
    {
        mysleep(5);
        printf("5 seconds after\n");
    }
    return 0;
} 

                              这里写图片描述
    上面代码是用来自主实现一个 sleep 函数. 先将 SIGALRM 信号注册,然后设定一个闹钟, 接着系统调用 pause 函数等待, 在 nsecs 秒之后, 闹钟设定的时间到了, 此时内核给进程发送一个 SIGALRM 信号, 当内核正要切回到用户态时, 发现一个可以递达的信后 SIGALRM, 它的处理动作是 sig_alrm, 此时内核有切回到 这个函数处取执行该信号的自定义动作, 在处理 sig_alrm 函数时, 系统将 SIGALRM 信号屏蔽, 当处理完这个函数时, 对 SIGALRM 函数解除屏蔽, 同时系统通过调用 sigreturn 函数返回到内核态, 接着从内核态返回到 主控制流处, 执行剩余的代码
    (1)也许会有人问信号处理 sig_alrm 函数时什么都没有干为什么还要注册, 原因很简单, 如果对 SIGALRM 信号不注册, 当注册一个 5 秒的闹钟信号时,5 秒之后该信号会被递达, 而此时的信号没有注册,信号的处理动作将会是终止进程, 此时进程终止, 程序退出, 而我们要实现的是将进程睡眠 5 秒钟, 那不就和我们的目的有冲突了吗?
    (2)也许还会有人问, 为什么在sleep函数之后需要对 SIGALRM 信号的默认处理动作进行恢复, 原因很简单. 加入这个代码很长, 而我们在 sleep 函数之后系统又用到了 SIGALRM 信号, 而此时我们的目的是在 n 秒之后操作系统给进程发送一个 SIGALRM 信号来终止信号, 而此时我们没有将该信号的处理动作进行恢复, 进程会去执行 sig_alrm 函数, 此时进程就不会在 5 秒之后退出
3. 可重入函数
    (1)定义 :
        重入的意思就是函数在被不同的执行流调用, 有可能在第一个执行流还没有执行完的时候又被第二个执行流调用. 而此时可能会由于重入导致一些错误, 此时的函数称为不可重入函数, 而当第一个执行流还没有执行完时, 第二个执行流进入, 此时没有导致函数执行功能发生错误, 此时这个函数就叫做可重入函数.
    (2)条件:
        如果一个函数调用了 malloc , free, 或者标准库 I/O函数,等全局变量的时候这个函数就叫做不可重入函数, 而如果一个函数只调用了自己的局部变量, 此时的函数叫做可重入函数,因为系统函数和主控制流各自独立拥有自己的堆栈, 不存在调用关系, 因此两个互不干扰

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值