可重入函数,SIGCHILD信号

一、 可重入函数

概念:一个函数被多个执行流进入,不会出错,这就叫可重入函数;否则,就叫不可重入函数。

1.如果一个函数只访问自己的局部变量或参数,当有多个执行流执行时,就不会互相影响。
2.首先它意味着这个函数可以被中断,其次意味着它除了使用自己栈上的变量以外不依赖于任何环境(包括 static),这样的函数就是可重入,可以允许有该函数的多个副本在运行,由于它们使用的是分离的栈,所以不会互相干扰。
3.如果确实需要访问全局变量(包括 static),一定要注意实施互斥手段。可重入函数在并行运行环境中非常重要,但是一般要为访问全局变量付出一些性能代价。

1.如何保证函数的可重入性?

1)在写函数时候尽量使用局部变量(例如寄存器、堆栈中的变量);
2)对于要使用的全局变量要加以保护(如采取关中断、信号量等互斥方法),这样构成的函数就一定是一个可重入的函数。

2.满足下列条件的函数多数是不可重入(不安全)的:

1)函数体内使用了静态的数据结构;
2)函数体内调用了malloc() 或者 free() 函数;
3)函数体内调用了标准 I/O 函数。

二、volatile限定符

编译器的优化:

硬件级别的优化:
1.由于内存的访问速度远不及CPU的处理速度,所以引入硬件高速缓存Cache,加速对内存的访问;
2.现代CPU的指令并不一定严格按照顺序执行,没有相关性的指令可以乱序执行,以充分利用CPU的指令流水线,提高执行速度。

软件级别的优化:
1.将内存变量缓存到寄存器,调整指令顺序

作用:告诉编译器不要优化它所修饰的变量,会改变编译结果


未被volatile修饰的变量每次操作时:
从内存中读取----->放入寄存器----->CPU计算操作1---->CPU计算操作2…------>写回内存

被volatile修饰的变量每次操作时:
从内存中读取----->放入寄存器----->CPU计算操作------>写回内存---->第二次从内存中读取

也就是说,被volatile修饰的变量能够保证每个线程能够获取该变量的最新值,从而避免出现数据脏读的现象。

volatile可以修饰不返回的函数,这样就不用把它的返回值载压入堆栈了,起到一定的优化效果

三、SIGCHLD信号

1.子进程在退出的时候,会给父进程发送 “SIGCHLD” 信号,该信号的默认处理动作是忽略。

2.虽然系统默认处理动作是忽略,但是如果父进程不 wait 的话,依然会使子进程变为僵尸进程,所以需要我们捕捉该信号,或者显式忽略它。为啥要显式的忽略它呢?(这是一个特例)

3.所以父进程可以自定义“SIGCHLD”信号的处理动作,当子进程退出时,可以调用该默认处理动作;这样父进程就不必阻塞等待了,提高了运行效率。

代码如下:

#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
using namespace std;

void handler(int signo)
{
    if(pid_t ret=(wait(NULL)) != -1)
    {
        cout << "child exit process" << ret <<endl;
    }
}
int main()
{
    struct sigaction act,oact;
    act.sa_handler=handler;
    act.sa_flags=0;
    sigemptyset(&act.sa_mask);
    sigaction(SIGCHLD,&act,&oact);
    pid_t id = fork();
    if(id == 0)
    {
        cout << "i am child run..." << endl;
        sleep(3);
        _exit(1);
    }
    else{
        while(1)
        {
            cout << "i am a parent:"<<getpid()<<endl;
            sleep(1);
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值