• UNIX IPC: POSIX 消息队列 与 信号


    POSIX消息队列可以注册空队列有消息到达时所触发的信号,而信号触发对应的信号处理函数。

    下面是一份基本的消息队列和信号处理结合的代码(修改自UNIX网络编程:进程间通信)

    #include <stdio.h>
    #include <stdlib.h>
    
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <mqueue.h>
    #include <signal.h>
    #include <pthread.h>
    
    
    mqd_t queue;
    void* buff;
    struct mq_attr attr;
    struct sigevent sigev;
    
    static void sig_user1(int signo) {
        printf("current pid:%d, threadid:%u
    ", getpid(), pthread_self());
        int n, prio;
        /*     signal will be unregistered from previous registered message queue 
            when first message arrived.
            So register signal again if we want trigger the signal handler again */
        mq_notify(queue, &sigev);
        
        /* read msg */
        int res = mq_receive(queue, buff, attr.mq_msgsize, &prio);
        if (res < 0) {
            perror("receive msg fail");
            exit(-1);
        }
        printf("prio: %d, msg: %s
    ", prio, (char*)buff);
        return;
    }
    
    int main(int argc, char** argv) {
        char* name = "/testmq";
        if (argc > 0) {
            name = argv[1];
        }
    
        queue = mq_open(name, O_RDONLY);
    
        if (queue < 0) {
            perror("open message queue fail");
            return -1;
        }
    
        int res = mq_getattr(queue, &attr);
        if (res != 0) {
            perror("get message queue fail");
            return -1;
        }
    
        buff = malloc(attr.mq_msgsize);
    
        signal(SIGUSR1, sig_user1);
    
        sigev.sigev_notify = SIGEV_SIGNAL;
        sigev.sigev_signo = SIGUSR1;
    
        mq_notify(queue, &sigev);
    
        printf("[%d.%d] start to waiting
    ", getpid(), pthread_self());
        for (;;) {
            pause();
        }
    
        return 0;
    }

    运行输出:

    hgf@ubuntu:~/ipc$ ./mqnotify /haha
    [25328.1410565952] start to waiting
    current pid:25328, threadid:1410565952

    可以看到主线程和执行信号处理的线程是同一个,这估计也是书上说以上程序存在问题,因为有些函数调用不应该放在信号处理函数当中。因为它们可能使用了互斥资源可能造成死锁,比如printf,当其正在处理时又来一个信号于是再次调用printf然后可能上一个printf还没有释放对一些互斥资源的所有权造成死锁。

  • 相关阅读:
    C++中的类访问控制
    Docker应用程序容器技术_转
    16C554(8250)驱动分析
    动态调频DVFS_转
    ubifs概述
    ubifs物理存储
    fmt-重新格式化段落
    uniq-删除重复
    sort
    join用法
  • 原文地址:https://www.cnblogs.com/lailailai/p/4318267.html
Copyright © 2020-2023  润新知