• Linux SYSV IPC 报文(消息)队列 收发demo


    Linux SYSV IPC 报文(消息)队列 demo

    linux下进程间通信(IPC)的几种主要手段简介:

    1. 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;
    2. 信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数);
    3. 报文(Message)队列(消息队列):消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
    4. 共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
    5. 信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
      套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。

    本来报文队列很适合手头上的工作,奈何Android Oseccomp 过滤器会阻止某些系统调用,报文队列就在其中,只能另寻他法。

    下面是一个利用sys/msg收发的demo

    收:

    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
    #include <sys/msg.h>
    #include <vector>
    
    #include<iostream>
    #include <sstream>
    class msg{
        struct msg_st{
            long int msg_type;
            char text[BUFSIZ];
        };
        struct msg_st data;
        int running = 1;
    	int msgid = -1;
    	long int msgtype = 0; //注意具有特殊含义
    
        public: std::vector<int> getint(){
            std::vector<int> ret;
            msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
            if(msgid == -1){
                return ret;
            }
            while(running){
    			int f = msgrcv(msgid, (void*)&data, BUFSIZ, msgtype, IPC_NOWAIT);
                if( f == -1 || f == ENOMSG ){
                    break;
                }
    			std::cout<<"rev:"<<data.text<<"
    "; 
                std::stringstream ss;
    			ss<<data.text;
                int x=0;
                ss>>x;
                ret.push_back(x);
            }
            return ret;
        }
    };
    
     
    int main()
    {
    	msg M;
    	auto v = M.getint();
    	for(int c:v) std::cout<<c<<std::endl;
    }
    

    发:

    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <sys/msg.h>
    #include <errno.h>
     
    #define MAX_TEXT 512
    struct msg_st
    {
    	long int msg_type;
    	char text[MAX_TEXT];
    };
    
    
    int main()
    {
    	int running = 1;
    	struct msg_st data;
    	char buffer[BUFSIZ];
    	int msgid = -1;
     
    	//建立消息队列
    	msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
    	if(msgid == -1)
    	{
    		fprintf(stderr, "msgget failed with error: %d
    ", errno);
    		exit(EXIT_FAILURE);
    	}
     
    	//向消息队列中写消息
    	while(running)
    	{
    		//输入数据
    		printf("Enter some text: ");
    		fgets(buffer, BUFSIZ, stdin);
    		data.msg_type = 1;    //注意具有特殊含义
    		strcpy(data.text, buffer);
    		//向队列发送数据
    		if(msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1)
    		{
    			fprintf(stderr, "msgsnd failed
    ");
    			exit(EXIT_FAILURE);
    		}
    		//输入end结束输入
    		if(strncmp(buffer, "end", 3) == 0)
    			running = 0;
    	}
    	exit(EXIT_SUCCESS);
    }
    
  • 相关阅读:
    .net基础学java系列(一)视野
    技术栈
    Apollo(阿波罗)携程开源配置管理中心
    .NET 动态调用WCF
    RPC 工作原理
    ServiceStack 简单使用
    PRC 框架选择
    栈vs堆,最详细的对比
    使用SuperSocket打造逾10万长连接的Socket服务
    开源项目练习EF+jQueryUI前后端分离设计
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/11250997.html
Copyright © 2020-2023  润新知