执行信号处理函数时,主进程的函数卡住

1,背景说明:

        1,信号处理函数install在主进程

        2,主进程执行initFunc函数,循环执行。

void InitFunc()
{
    pthread_mutex_init(&t_Test.comm_mutex,NULL);
    pthread_cond_init(&t_Test.comm_cond,NULL);
    sleep(1);

    while(true)
    {
        printf("wait unlock !!!!! id = %d\n",pthread_self());
        sleep(1);
        struct timespec ts;
        clock_gettime(CLOCK_REALTIME, &ts);
        ts.tv_sec += 5; 
        pthread_mutex_lock(&t_Test.comm_mutex);
        int pid = getpid();
        printf("init pid = %d\n",pid);
        int ret = pthread_cond_timedwait(&t_Test.comm_cond,&t_Test.comm_mutex,&ts);
        pthread_mutex_unlock(&t_Test.comm_mutex);
        if(ret == 0)
        {
            printf("received brocast signal\n");
            is_exit_flag = true;
            break;
        }
        else if(ret == ETIMEDOUT)
        {
            printf("timeout continue\n");
            continue;
        }
        else
        {
            printf("unavaild message\n");
        }

    }
}

3,此时信号处理函数收到退出信号执行ExitFunc,发现无法退出。

void ExitFunc()
{
    printf("start exit\n");
    static int count = 0;

    printf("send brocast signal %d\n",count);
    pthread_mutex_lock(&t_Test.comm_mutex);
    pthread_cond_broadcast(&t_Test.comm_cond);
    pthread_mutex_unlock(&t_Test.comm_mutex);
    count++;
    
    while(is_exit_flag == false)
    {
        
        int pid = pthread_self();
        printf("wait is_exit_flag relex true!!!! exit pid = %d\n",pid);
        sleep(1);
    }

}

2,问题原因

代码原因:

当信号处理函数执行时,主进程的其他部分会被暂停,直到该信号处理函数执行完毕并返回。

这意味着在信号处理函数执行期间,主进程不会同时执行其他函数或代码。

操作系统会确保同一进程中的信号处理函数是串行执行的,以避免竞争条件和不确定性。

这也是为什么在信号处理函数中应该尽量保持简单和高效,避免长时间的阻塞和耗时操作。

状态切换:

当信号处理函数被调用时,会涉及到系统用户态和内核态之间的切换。在Linux系统中,当进程接收到一个信号时,操作系统会进行以下步骤:

  1. 用户态到内核态的切换:当信号发生时,进程正常的用户态执行会被中断,操作系统将控制权转移到内核态,并且在内核中执行相应的信号处理程序。

  2. 信号处理程序执行:在内核态,操作系统会根据进程注册的信号处理函数来执行相应的处理程序。这个处理程序可能是默认的处理方式,也可以是进程自定义的信号处理函数。

  3. 内核态到用户态的切换:当信号处理程序执行完毕后,操作系统将控制权重新交还给进程的用户态执行环境,进程恢复执行。

这种用户态到内核态的切换是由操作系统负责管理的,它需要保存和恢复进程的上下文信息,包括寄存器的状态、堆栈指针等,以便在切换回用户态时能够正确地恢复进程的执行现场。

在整个信号处理过程中,用户态和内核态之间的切换是由操作系统内核来管理的,对于应用程序来说,这些切换是透明的,应用程序只需要关注信号处理函数的编写和注册即可。

程序在执行信号处理函数时,把程序的执行权限交给内核态,此时内核态只执行信号处理函数,用户态的函数就无法被执行,只有在信号处理函数完成之后,切换状态到用户态,此时才能执行用户态的函数。

3,解决办法

信号处理函数中尽量减少函数调用,避免产生死循环,可以把设置某个条件变量后,再用这个条件变量处理其他业务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想找后端开发的小杜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值