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\n", 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\n", 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\n", getpid(), pthread_self());
    for (;;) {
        pause();
    }

    return 0;
}

运行输出:

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

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

时间: 2024-08-06 18:01:36

UNIX IPC: POSIX 消息队列 与 信号的相关文章

UNIX IPC: POSIX 消息队列

首先在我的MAC OSX上试了一下虽然有_POSIX_MESSAGE_PASSING的宏定义,但是用gcc编译会提示没有mqueue.h头文件,先放一边.在Ubuntu上使用正常,不过POSIX消息队列通过ipcs命令是看不到的,需要通过如下方式进行查看: mount -t mqueue none /mnt ls -al /mnt ls列出的文件即为程序中创建的POSIX消息队列,消息队列的名称需要以“/”开头否则会提示参数非法.通过cat查看这个文件可以知道这个队列的一些参数如: [email

Unix IPC之Posix消息队列(1)

部分参考:http://www.cnblogs.com/Anker/archive/2013/01/04/2843832.html IPC对象的持续性:http://book.51cto.com/art/201006/207275.htm 消息队列可以认为是一个消息链表,某个进程往一个消息队列中写入消息之前,不需要另外某个进程在该队列上等待消息的达到,这一点与管道和FIFO相反.Posix消息队列与System V消息队列的区别如下: 1. 对Posix消息队列的读总是返回最高优先级的最早消息,

Linux进程间通信(IPC)编程实践(十二)Posix消息队列--基本API的使用

posix消息队列与system v消息队列的差别: (1)对posix消息队列的读总是返回最高优先级的最早消息,对system v消息队列的读则可以返回任意指定优先级的消息. (2)当往一个空队列放置一个消息时,posix消息队列允许产生一个信号或启动一个线程,system v消息队列则不提供类似机制. 队列中的每个消息具有如下属性: 1.一个无符号整数优先级(posix)或一个长整数类型(system v) 2.消息的数据部分长度(可以为0) 3.数据本身(如果长度大于0) Posix消息队

Linux IPC实践(7) --Posix消息队列

1. 创建/获取一个消息队列 #include <fcntl.h> /* For O_* constants */ #include <sys/stat.h> /* For mode constants */ #include <mqueue.h> mqd_t mq_open(const char *name, int oflag); //专用于打开一个消息队列 mqd_t mq_open(const char *name, int oflag, mode_t mode

细说linux IPC(九):posix消息队列

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet 或 .../gentleliu,文章仅供学习交流,请勿用于商业用途] 消息队列可以看作一系列消息组织成的链表,一个程序可以往这个链表添加消息,另外的程序可以从这个消息链表读走消息. mq_open()函数打开或创建一个posix消息队列. #include <fcntl.h> /* For O_* constants */ #include <sys/stat.h> /* For mode cons

Linux环境编程之IPC进程间通信(五):Posix消息队列1

对于管道和FIFO来说,必须应该先有读取者存在,否则先有写入者是没有意义的.而消息队列则不同,它是一个消息链表,有足够写权限的线程可往别的队列中放置消息,有足够读权限的线程可从队列中取走消息.每个消息都是一个记录,它由发送者赋予一个优先级.在某个进程往一个队列写入消息之前,并不需要另外某个进程在该队列上等待消息的到达.消息队列是随内核的持续性,一个进程可以往某个队列写入一些消息,然后终止,再让另外一个进程在以后的某个时刻读出这些消息.这跟管道和FIFO不一样,当一个管道或FIFO的最后一次关闭时

[转]Linux进程通信之POSIX消息队列

进程间的消息队列可以用这个实现,学习了下. http://blog.csdn.net/anonymalias/article/details/9799645?utm_source=tuicool&utm_medium=referral 消息队列是Linux IPC中很常用的一种通信方式,它通常用来在不同进程间发送特定格式的消息数据. 消息队列和之前讨论过的管道和FIFO有很大的区别,主要有以下两点: 一个进程向消息队列写入消息之前,并不需要某个进程在该队列上等待该消息的到达,而管道和FIFO是相

进程间通信(IPC)之消息队列

★IPC方法包括管道(PIPE).消息队列(Message_Queue).旗语.共用内存(ShareMemory)以及套接字(Socket).进 程间通信主要包括了管道.系统IPC(包括了消息队列.信号以及共享存储).套接字(SOCKET).此文将详细叙述消息队列的相 关内容. ★产生原因: 所谓消息队列,其实就是消息(数据)传输过程中保存的容器.既然有了管道通信的方式,何必又有消息队列呢? 因为根据管道的特性,我们知道其在一定程度上存在或多或少的局限性,首先匿名管道以及命名管道是随进程的,进

POSIX 消息队列

POSIX消息队列与System V消息队列的主要区别:1.对POSIX队列的读总数返回最高优先级到最早消息,对SV队列到读则可以返回任意指定优先级的消息2.当往一个空队列放置一个消息时,POSIX允许产生一个信号或启动一个线程,System V不提供此机制 消息的属性:1.一个无符号整数的优先级(POSIX)或一个长整数的类型(SV)2.消息的数据部分长度(可以为0)3.数据本身(如果长度大于0) POSIX消息队列总结:mq_open创建一个新队列或者打开一个已经存在的队列mq_close关