代码:
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.c(gcc 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.c(gcc 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端即可!