• Linux下C语言进程通讯编程


    代码:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <sys/shm.h>
     4 /*************基本的函数API********************
     5 共享内存函数API
     6 int shmget(key_t key, int size, int flag)
     7 key:
     8     共享内存的键值,多个进程可以通过它访问同一个共享内存。常用特殊值:IPC_PRIVATE,创建当前进程的私有共享内存
     9 size:
    10     指定创建共享内存的大小
    11 flag:
    12     操作权限
    13 char * shmat(int shm_id, const void * addr, int flag)
    14 shm_id:
    15     要映射的共享内存标识符
    16 addr:
    17     指定在调用进程中映射共享内存的地址。通常取值为0,表示由系统自动分配地址。
    18 flag:
    19     设置共享内存的操作权限。若取值为0,表示可对共享内存进行读写操作。
    20 int shmctl(int shm_id, int cmd, struct shmid_ds * buf)
    21 shm_id:
    22     共享内存标识符
    23 cmd:
    24     指定索要进行的操作:IPC_STAT IPC_SET IPC_RMID SHM_LOCK SHM_UNLOCK
    25 buf:
    26     结构体型指针
    27 int shmdt(const void * addr)
    28 **********************************************/
    29 #define Test_pipe 0
    30 #define Test_Shmget 0
    31 #define Test_AT_w 0
    32 #define Test_AT_r 0
    33 #define Test_DT 1
    34 int main(int argc, char *argv[])
    35 {
    36 #if Test_pipe
    37     int x,fd[2];
    38     char buf[30],s[30];
    39     pipe(fd);
    40     x = fork();
    41     if(0 == x)
    42     {
    43         sprintf(buf,"This is an pipe!");
    44         write(fd[1],buf,30);
    45         exit(0);
    46     }
    47     else
    48     {
    49         wait(0);
    50         read(fd[0],s,30);
    51         printf("read: %s
    ",s);
    52     }
    53 #endif
    54 
    55 #if Test_Shmget
    56     int shm_id;
    57     shm_id = shmget(IPC_PRIVATE,4096,0666);
    58     if(shm_id < 0)
    59     {
    60         perror("shmget id < 0");
    61         exit(0);
    62     }
    63     printf("成功建立共享内存区域: %d
    ",shm_id);
    64     system("ipcs -m");
    65 #endif
    66 
    67 #if Test_AT_w
    68     int shm_id;
    69     char *shm_buf;
    70     shm_id = atoi(argv[1]);
    71     shm_buf = shmat(shm_id,0,0);
    72     printf("写如数据到共享内存:
    ");
    73     sprintf(shm_buf,"对共享内存的读写操作!");
    74     printf("%s
    ",shm_buf);
    75 #endif
    76 
    77 #if Test_AT_r
    78         int shm_id;
    79         char *shm_buf,str;
    80         shm_id = atoi(argv[1]);
    81         shm_buf = shmat(shm_id,0,0);
    82         printf("写如数据到共享内存:
    ");
    83         sprintf(str,shm_buf);
    84         printf("%s
    ",str);
    85     system("ipcs -m");
    86 #endif
    87 
    88 #if Test_DT
    89         int shm_id;
    90         char *shm_buf;
    91         shm_id = atoi(argv[1]);
    92         shm_buf = shmat(shm_id,0,0);
    93     shmdt(shm_buf);
    94     shmctl(shm_id,IPC_RMID,NULL);
    95     system("ipcs -m");
    96 #endif
    97 }

    IPC通讯中共享内存参看代码:

    Client端代码client.cgcc client.c -lm -o client) 

    shmget函数得到的共享内存的大小有参数确定,参数的单位是Byte!

    同样的shmget参数的0666代表的内容是,共享内存空间的可读可写性!

    使用ftok函数获取的key_t key的作用在于生成一个文件节点引索,这样才能够连接两个进程让他们以这个引索值作为标识ID!

    shmdt函数用来删除释放掉创建的共享内存空间!

    shmat函数用来映射已经创建好的虚拟内存空间地址!返回值为两个进程进行操作的共享内存起始地址!

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <time.h>
    #include <math.h>
    
    #define random(x) (rand()%x)
    #define PI 3.1415926
    
    #define Width 20
    #define Height 20
    
    int main(int argc,char *argv[])
    {
            key_t key = 0;
            int shmid = 0;
            setbuf(stdout,NULL);
            printf("Begin to Create the shared-mem...
    ");
            key = ftok(".",2); // Get the only IPC ID:inode'num + 1
            if(key<0)
            {       
                    perror("ftok");
                    return -1;
            }
            printf("key=%d
    ",key);
            sleep(1);
            printf("...
    ");
            printf("%d
    ",IPC_CREAT);
            shmid = shmget(key,100,IPC_EXCL | IPC_CREAT | 0666); // Get shared mem:IPC_ID_key Mem_size
            if(shmid<0)
            {
                    perror("shmget");
                    return -2;
            }
            char * shared_mem_addr = shmat(shmid,NULL,0); // mapping the mem_addr to the addr of the Process
            printf("...
    ");
    
            sleep(2); // waitting for setup the mem
    
            printf("The shared-mem create sucessfully!
    ");
            printf("Begin to insert the data into shared-mem!
    ");
            int i=0;
            while(i<Width*Height)
            {
                    *(shared_mem_addr+i) = 200*sin((double)i*PI/180.0);// random(255)+255;
                    usleep(100);
                    printf(".");
                    i++;
            }
            printf("
    The data insert finish!
    ");
            shmdt(shared_mem_addr);
            return 0;
    }

    Server端代码server.cgcc server.c -o server

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <time.h>
    
    #define Width 20
    #define Height 20
    
    int main(int argc,char *argv[])
    {
            key_t key = 0;
            int shmid = 0;
            key = ftok(".",2); // Get the only IPC ID:inode'num + 1
            if(key<0)
            {
                    perror("ftok");
                    return -1;
            }
            shmid = shmget(key,100,IPC_CREAT | 0666); // Get shared mem:IPC_ID_key Mem_size
            if(shmid<0)
            {
                    perror("shmget");
                    return -2;
            }
            char * shared_mem_addr = shmat(shmid,NULL,0); // mapping the mem_addr to the addr of the Process
    
            sleep(2);
    
            int i=0;
            while(i<Width*Height)
            {
                    printf("The image data:%d
    ",*(shared_mem_addr+i));
                    usleep(100);
                    i++;
            }
            shmdt(shared_mem_addr);
            sleep(1);
            shmctl(shmid,IPC_RMID,NULL);
            return 0;
    }

    首先运行Clent端,然后再运行Server端即可!

    参看IPC通讯介绍:https://www.cnblogs.com/CheeseZH/p/5264465.html

  • 相关阅读:
    js上传文件
    IOS怎么实现一个UITableView的下拉刷新
    Android的事件处理-android学习之旅(四十四)
    NIO框架之MINA源代码解析(二):mina核心引擎
    每日五题
    Joda-Time 简介
    用websocket实现后台推送消息
    websoclet简单示例 my 改
    struts2拦截器interceptor的配置方法及使用
    activiti复盘重推的一种简单实现方式:
  • 原文地址:https://www.cnblogs.com/uestc-mm/p/7630154.html
Copyright © 2020-2023  润新知