• Linux 进程间通信(一)


    Linux 进程间通信

      进程是一个独立的资源分配单位,不同进程之间的资源是相互独立的,没有关联,不能在一个进程中直接访问另一个进程中的资源。但是,进程不是孤立的,不同的进程之间需要信息的交换以及状态的传递,因此需要进程间数据传递、同步与异步的机制。

    分类

    • 统一主机间进程通信
      • Unix进程间通信方式
        • 无名通道
        • 有名通道
        • 信号
      • System V进程间通信方式
        • 信号量
        • 消息队列
        • 共享内存
    • 不同主机间进程通信
        • RPC
        • Socket

    消息队列IPC

    简单介绍下,所有相关的API函数:

    API函数 用途
    msgget   创建一个新的消息队列       
      获取消息队列ID
    msgsnd        向消息队列发送消息
    msgrcv 从消息队列接受消息
    msgctl 获得消息队列的信息
      设置消息队列的信息
      删除消息队列

    函数原型如下:

    // 函数原型
    #include <sys/msg.h>
     
    int msgget( key_t key, int msgflag);
    /*
    key为消息队列的描述符
    msgflag是一个设置选项,可以设置权限
    
    返回值为消息队列ID
    */
    
    int msgctl( int msgid, int cmd, struct msqid_ds *buf);
    /*
    msgid是msgget的返回值
    cmd :IPC_STAT 获取消息队列当前的状态信息,保存到buf指向的空间
                 IPC_SET  设置消息队列的属性
                 IPC_RMID 从内核中删除msgid标识的消息队列
    */
    
    int msgsnd( int msgid, struct msgbuf *msgp, size_t msgsz, int msgflag);
    /*
    msgid为消息队列ID
    msgbuf 指向要发送的消息
    msgsize 消息的大小
    msgflag 操作标志位
    */
    
    int msgrcv(int msgid, struct msgbuf *msgbuf, size_t msgsize, long int msgtype, int msgflag);
    /*
    msgtype用来指定要接收的消息,分三种情况:
    等于 0 返回消息队列中的第一个消息
    大于0  返回消息队列中类型为msgtype的第一个消息
    小于0 返回消息队列中类型值小于等于msgtype绝对值的消息中类型值最小的第一条消息
    */

    例子:

     1 #include <stdio.h>
     2 #include <sys/msg.h>
     3 #include <sys/types.h>
     4 #include <sys/ipc.h>
     5 
     6 int main()
     7 {
     8     int msgid;
     9     
    10     //通过这样可以避免标识符的重复
    11     //key_t myKey;
    12     //myKey = ftok("/home/queues/myqueue", 0);
    13 
    14     msgid = msgget( 0x111, IPC_CREAT|0666);
    15     if(msgid >= 0)
    16         printf("Created a Msg Queue %d
    ", msgid);
    17         
    18     return 0;
    19 }
    20 
    21 创建消息队列
    创建消息队列
     1 #include <stdio.h>
     2 #include <sys/msg.h>
     3 #include <sys/types.h>
     4 
     5 int main(int argc, char **argv)
     6 {
     7     int msgid, ret;
     8     struct msqid_ds buf;
     9     
    10     //获取消息队列
    11     msgid = msgget(0x111, 0);
    12     
    13     if(msgid >= 0){
    14         ret = msgctl(msgid, IPC_STAT, &buf);
    15         buf.msg_qbytes = 4096;
    16         
    17         ret = msgctl(msgid, IPC_SET, &buf);
    18         
    19         if(ret == 0){
    20             printf("change queue size success");
    21         }
    22     }
    23     
    24     return 0;
    25 }
    配置消息队列
     1 #include <stdio.h>
     2 #include <sys/msg.h>
     3 #include <sys/types.h>
     4 #include <string.h>
     5 
     6 typedef struct{
     7     long type;
     8     float fval;
     9     unsigned int unival;
    10     char message[1024];
    11 }myType;
    12 
    13 int main()
    14 {
    15     myType msg;
    16     int qid,ret;
    17     
    18     qid = msgget(0x111, 0);
    19     if(qid > 0){
    20         msg.type = 1L;
    21         msg.fval = 123.456;
    22         msg.unival = 256;
    23         strcpy( msg.message, "this is a msg in queue
    ");
    24         
    25         ret = msgsnd(qid, (struct msgbuf*)&msg, sizeof(myType), 0);
    26         if(ret != -1)
    27             printf("sent success!
    ");
    28     }
    29     
    30     return 0;
    31 }
    向消息队列发送消息
     1 #include <stdio.h>
     2 #include <sys/msg.h>
     3 #include <sys/types.h>
     4 #include <string.h>
     5 
     6 typedef struct{
     7     long type;
     8     float fval;
     9     unsigned int unival;
    10     char message[1024];
    11 }myType;
    12 
    13 int main()
    14 {
    15     myType msg;
    16     int qid,ret;
    17     
    18     qid = msgget(0x111, 0);
    19     if(qid >= 0){
    20         
    21         ret = msgsnd(qid, (struct msgbuf*)&msg, sizeof(myType), 0);
    22         if(ret != -1)
    23             printf("recv success!
    ");
    24             printf("type : %ld
    ", msg.type);
    25             printf("float value: %f
    ", msg.fval);
    26             printf("Unit value: %d
    ", msg.unival);
    27             printf("String value: %s
    ", msg.message);
    28     }
    29     
    30     return 0;
    31 }
    从消息队列读取消息

    共享内存

      使用消息队列时,一个进程要向队列中写入消息,这要引起从用户地址空间的一次复制,当另外一个进程要从消息队列中读取消息时,又要进行一次从内核空间向用户空间的一次复制。而共享内存的优点就是完全省去了这些复制操作。

      简单介绍下API函数:

    API函数 用途                                                                                             
    shmget             创建一个新的共享内存区段
      取得一个已经创建的共享内存区段的描述符
    shmctl 取得一个共享内存区段的信息
      为一个共享内存区段设置特定的信息
      删除一个共享内存区段
    shmat 挂接一个共享内存区段
    shmdt 与一个共享内存区段分离

       函数原型如下:

    //函数原型
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <sys/types.h>
    
    int shmget( key_t key, size_t size, int shmflag );
    /*
    key为描述符
    size为共享内存区段的大小
    shmflag为指令和权限设置
    */
    
    int shmctl( int shmid, int cmd, struct shmid_ds *buf );
    /*
    shmid指共享内存ID
    cmd为指令
    */
    
    void *shmat( int shmid, const void *shmaddr, int shmflag);
    /*
    shmaddr指定共享内存出现在进程内存地址的什么位置,直接指定为NULL让内核自己决定一个合适的地址位置
    shmflg SHM_RDONLY:为只读模式,其他为读写模式
    */
    
    int shmdt( const void *shmaddr );

    例子:

     1 #include <stdio.h>
     2 #include <sys/ipc.h>
     3 #include <sys/shm.h>
     4 
     5 int main()
     6 {
     7     int shmid;
     8     
     9     shmid = shmget( 0x123, 4096, IPC_CREAT|0666);
    10     if(shmid >= 0)
    11         printf("Created a shared memory %d
    ", shmid);
    12         
    13     return 0;
    14 }
    创建共享内存
     1 #include <stdio.h>
     2 #include <sys/shm.h>
     3 #include <errno.h>
     4 #include <sys/ipc.h>
     5 #include <sys/types.h>
     6 
     7 int main(int argc, char **argv)
     8 {
     9     int shmid, ret;
    10     struct shmid_ds shmds;
    11     
    12     //获取共享内存
    13     shmid = shmget(0x123, 0, 0);
    14     
    15     if(shmid >= 0){
    16         ret = shmctl(shmid, IPC_STAT, &shmds);
    17         if(ret == 0){
    18             printf("shared memory size : %d/n", shmds.shm_segsz);
    19             printf("attaches number: %d/n", (int)shmds.shm_nattch);
    20         }else
    21             printf("shmctl error!
    ");
    22     }else
    23         printf("shared memory not found!
    ");
    24     
    25     return 0;
    26 }
    取得共享内存
     1 #include <stdio.h>
     2 #include <sys/shm.h>
     3 #include <errno.h>
     4 #include <sys/ipc.h>
     5 #include <sys/types.h>
     6 #include <string.h>
     7 
     8 int main(int argc, char **argv)
     9 {
    10     int shmid, ret;
    11     void* mem;
    12     
    13     //获取共享内存
    14     shmid = shmget(0x123, 0, 0);
    15     
    16     if(shmid >= 0){
    17         
    18         mem = shmat( shmid, (const void*)0, 0 );
    19         
    20         strcpy((char*)mem, "This is a shared memory
    ");
    21         
    22         ret = shmdt(mem);
    23         
    24     }else
    25         printf("shared memory not found!
    ");
    26     
    27     return 0;
    28 }
    写入共享内存
     1 #include <stdio.h>
     2 #include <sys/shm.h>
     3 #include <errno.h>
     4 #include <sys/ipc.h>
     5 #include <sys/types.h>
     6 #include <string.h>
     7 
     8 int main(int argc, char **argv)
     9 {
    10     int shmid, ret;
    11     void* mem;
    12     
    13     //获取共享内存
    14     shmid = shmget(0x123, 0, 0);
    15     
    16     if(shmid >= 0){
    17         
    18         mem = shmat( shmid, (const void*)0, 0 );
    19         
    20         printf("%s", (char*)mem);
    21         
    22         ret = shmdt(mem);
    23         
    24     }else
    25         printf("shared memory not found!
    ");
    26     
    27     return 0;
    28 }
    读取共享内存
     1 #include <stdio.h>
     2 #include <sys/shm.h>
     3 #include <errno.h>
     4 #include <sys/ipc.h>
     5 #include <sys/types.h>
     6 
     7 int main(int argc, char **argv)
     8 {
     9     int shmid, ret;
    10     
    11     //获取共享内存
    12     shmid = shmget(0x123, 0, 0);
    13     
    14     if(shmid >= 0){
    15         ret = shmctl(shmid, IPC_RMID, 0);
    16         if(ret == 0){
    17             printf("shared memory removed!");
    18         }else
    19             printf("shmctl error!
    ");
    20     }else
    21         printf("shared memory not found!
    ");
    22     
    23     return 0;
    24 }
    删除共享内存

    参考

    GNU/Linux环境编程

    http://blog.sina.com.cn/s/blog_7f98bac10100s91d.html

    http://www.cnblogs.com/joeblackzqq/archive/2011/05/31/2065161.html 

    知识共享许可协议
    Linux 进程间通信cococo点点 创作,采用 知识共享 署名-非商业性使用-相同方式共享 3.0 中国大陆 许可协议进行许可。欢迎转载,请注明出处:转载自:cococo点点 http://www.cnblogs.com/coder2012
  • 相关阅读:
    greendao的基本操作
    编写clearedit的安卓控件
    获得edittext的图片大小
    设置edittext的样式
    安卓topbar编码实战
    安卓titlebar的组合控件使用
    安卓中使用iconfont
    async的用法
    fastjson解析服务端返回的数据
    安卓数据持久化
  • 原文地址:https://www.cnblogs.com/coder2012/p/3213738.html
Copyright © 2020-2023  润新知