• 进程间通信:消息队列


    http://blog.csdn.net/ljianhui/article/details/10287879

    #include <sys/type.h>
    #include <sys/ipc.h>
    #include <sys/msg.h>
    int msgget(key_t key, int flag);
    int msgsnd(int msqid, const void *ptr, size_t nbytes, int flag);
    int msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag);
    int msgctl(int msqid, int cmd, struct mspid_ds *buf);

    int msgget(key_t key, int flag);

    msgflg是一个权限标志,表示消息队列的访问权限,它与文件的访问权限一样。msgflg可以与IPC_CREAT做或操作,表示当key所命名的消息队列不存在时创建一个消息队列,如果key所命名的消息队列存在时,IPC_CREAT标志会被忽略,而只返回一个标识符。它返回一个以key命名的消息队列的标识符(非零整数),失败时返回-1.

    int msgsnd(int msqid, const void *ptr, size_t nbytes, int flag);


    int msgrcv(int msqid, void *ptr, size_t nbytes, long msgtype, int flag);

    msgtype可以实现一种简单的接收优先级。如果msgtype为0,就获取队列中的第一个消息。如果它的值大于零,将获取具有相同消息类型的第一个信息。如果它小于零,就获取类型等于或小于msgtype的绝对值的第一个消息。

    flag取值包括0(阻塞)和IPC_NOWAIT(如果消息队列为空,则返回一个ENOMSG)

    int msgctl(int msqid, int cmd, struct mspid_ds *buf);

    cmd是将要采取的动作,它可以取3个值,
        IPC_STAT:把msgid_ds结构中的数据设置为消息队列的当前关联值,即用消息队列的当前关联值覆盖msgid_ds的值。
        IPC_SET:如果进程有足够的权限,就把消息列队的当前关联值设置为msgid_ds结构中给出的值
        IPC_RMID:删除消息队列
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/msg.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <pthread.h>
    #include <pthread.h>
    #include <sys/syscall.h>
    #include <unistd.h>
    
    
    /*
    
    #include <sys/type.h>
    #include <sys/ipc.h>
    #include <sys/msg.h>
    int msgget(key_t key, int flag);
    int msgsnd(int msqid, const void *ptr, size_t nbytes, int flag);
    int msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag);
    int msgctl(int msqid, int cmd, struct mspid_ds *buf);
    
    
    */
    
    #ifndef T_DESC
    #define T_DESC(x, y)   (y)
    #endif
    
    #if T_DESC("TU1", 1)
    
    int msg_qid;
    
    typedef struct msgbuf
        {
            long msgtype;
            char msgtext[128];
        } PRIV_MSG_INFO;
    
    int send_task(void)  
    {
        PRIV_MSG_INFO sndmsg;
    
        for(;;)
        {
            sndmsg.msgtype++;
            sprintf(sndmsg.msgtext, "type %ld", sndmsg.msgtype);
            if(msgsnd(msg_qid, (PRIV_MSG_INFO *)&sndmsg, sizeof(PRIV_MSG_INFO), 0)==-1)
            {
                printf("msgsnd error
    ");
                exit(254);
            }
            sleep(3);
        }
    }
    
    int recv_task(void)  
    {
        PRIV_MSG_INFO rcvmsg;
    
        for(;;)
        {
            if(msgrcv(msg_qid, (PRIV_MSG_INFO *)&rcvmsg, sizeof(PRIV_MSG_INFO), 0, 0) == -1)
            {
                printf("msgsnd error
    ");
                exit(254);
            }
            printf("recv msg: %s
    ", rcvmsg.msgtext);
        }
    }
    
    int tu1_proc(void)  
    {  
        pthread_t id_1,id_2;  
        int i,ret;  
    
        msg_qid = msgget(IPC_PRIVATE, 0666);
        if(msg_qid == -1)
        {
            printf("msgget error
    ");
            exit(254);
        }
    
        ret = pthread_create(&id_1, NULL, (void *)send_task, NULL);  
        if(ret != 0)  
        {  
            printf("Create pthread error!
    ");  
            return -1;  
        }  
        
        ret = pthread_create(&id_2, NULL, (void *)recv_task, NULL);  
        if(ret != 0)  
        {  
            printf("Create pthread error!
    ");  
            return -1;  
        }  
        
        /*µÈ´ýÏ߳̽áÊø*/  
        pthread_join(id_1, NULL);  
        pthread_join(id_2, NULL);  
    
        msgctl(msg_qid, IPC_RMID, 0);
    
        return 0;  
    }  
    
    
    #endif
    
    #if T_DESC("TU2", 1)
    
    int send_task2(void)  
    {
        PRIV_MSG_INFO sndmsg;
    
        msg_qid = msgget((key_t)1234, 0666 | IPC_CREAT);  
        if(msg_qid == -1)
        {
            printf("msgget error
    ");
            exit(254);
        }
    
        for(;;)
        {
            sndmsg.msgtype=10;
            sprintf(sndmsg.msgtext, "type %ld", sndmsg.msgtype);
            if(msgsnd(msg_qid, (PRIV_MSG_INFO *)&sndmsg, sizeof(PRIV_MSG_INFO), 0)==-1)
            {
                printf("msgsnd error
    ");
                exit(254);
            }
            
            sndmsg.msgtype=20;
            sprintf(sndmsg.msgtext, "type %ld", sndmsg.msgtype);
            if(msgsnd(msg_qid, (PRIV_MSG_INFO *)&sndmsg, sizeof(PRIV_MSG_INFO), 0)==-1)
            {
                printf("msgsnd error
    ");
                exit(254);
            }
            sleep(3);
        }
    }
    
    int recv_task2(void)  
    {
        PRIV_MSG_INFO rcvmsg;
    
        msg_qid = msgget((key_t)1234, 0666 | IPC_CREAT);  
        if(msg_qid == -1)
        {
            printf("msgget error
    ");
            exit(254);
        }
    
        for(;;)
        {
            if(msgrcv(msg_qid, (PRIV_MSG_INFO *)&rcvmsg, sizeof(PRIV_MSG_INFO), 10, 0) == -1)
            {
                printf("msgsnd error
    ");
                exit(254);
            }
            printf("recv msg: %s
    ", rcvmsg.msgtext);
        }
    }
    
    int tu2_proc(int argc, char **argv)  
    {  
        pthread_t id_1,id_2;  
        int i,ret;  
        int param;
    
        if (argc < 2) return 1;
        param = atoi(argv[1]);
    
        if (!param) {
            ret = pthread_create(&id_1, NULL, (void *)send_task2, NULL);  
        } else {
            ret = pthread_create(&id_2, NULL, (void *)recv_task2, NULL);  
        }
        if(ret != 0)  
        {  
            printf("Create pthread error!
    ");  
            return -1;  
        }  
        
        /*µÈ´ýÏ߳̽áÊø*/  
        if (!param) {
            pthread_join(id_1, NULL);  
        } else {
            pthread_join(id_2, NULL);  
        }
        
        return 0;  
    }  
      
    #endif
    
    #if T_DESC("global", 1)
    
    void usage()
    {
        printf("
     Usage: <cmd> <tu> <p1> <...>");
        printf("
       1 -- msgQ between thread");
        printf("
       2 -- msgQ between process");
        printf("
         => P1: 0 - create pid 0; 1 - create pid 1");
        printf("
    ");
    }
    
    int main(int argc, char **argv)
    {
        int ret;
        
        if(argc < 2) {
            usage();
            return 0;
        }
    
        int tu = atoi(argv[1]);
        if (tu == 1) ret = tu1_proc();
        if (tu == 2) ret = tu2_proc(argc - 1, &argv[1]);
        
        return ret;
    }
    #endif
  • 相关阅读:
    maven 利用 profile 进行多环境配置
    基于 TrueLicense 的项目证书验证
    SpringMVC 自定义参数解析器.
    Spring MVC -- 基于注解的控制器
    Spring MVC -- Spring MVC入门
    Spring MVC -- MVC设计模式(演示4个基于MVC框架的案例)
    Spring MVC -- Spring框架入门(IoC、DI以及XML配置文件)
    Servlet2.5版本和Servlet3.0版本
    Java基础 -- 深入理解泛型
    Java基础 -- 深入理解Java类型信息(Class对象)与反射机制
  • 原文地址:https://www.cnblogs.com/soul-stone/p/6683008.html
Copyright © 2020-2023  润新知