本文共 9909 字,大约阅读时间需要 33 分钟。
read.cpp$ mkfifo pipe
include#include #include #include #include int main(){ int fd=open("./pipe",O_RDONLY); if(fd<0) { std::cout<<"打开管道文件失败!"<
write.cpp
1 #include2 #include 3 #include 4 #include 5 #include 6 int main() 7 { 8 int fd=open("./pipe",O_WRONLY); 9 if(fd<0) 10 { 11 std::cout<<"打开管道文件失败!"<
[yyw@VM-0-9-centos 创建命名管道]$ ls / > pipe
[yyw@VM-0-9-centos 创建命名管道]$ cat < pipe
1 #include2 #include 3 #include 4 int main() 5 { 6 mkfifo("pipe",0664); 7 return 0; 8 }
实现客户端与服务端的通信:
1 #include2 #include 3 #include 4 #include 5 #include 6 7 #define FIFO_FILE "./fifo" 8 int main() 9 { 10 umask(0); 11 if(mkfifo(FIFO_FILE,0666)==-1) 12 { 13 printf("创建管道失败!\n"); 14 return 1; 15 }//创建管道 16 17 18 int fd=open(FIFO_FILE,O_RDONLY);// 19 if(fd<0) 20 { 21 printf("打开管道失败!\n"); 22 return 1; 23 } 24 else if(fd >=0) 25 { 26 char buf[64]; 27 while(1) 28 { 29 printf("please wait!\n"); 30 ssize_t s=read(fd,buf,sizeof(buf)-1);//减一是预留\0位置 31 if(s>0) 32 { 33 buf[s]=0; 34 printf("client# %s",buf); 35 } 36 else if(s==0) 37 { 38 printf("cilent exit!\n"); 39 break; 40 } 41 else 42 { 43 printf("文件读取失败!\n"); 44 break; 45 } 46 } 47 } 48 return 0; 49 }
1 #include2 #define FIFO_FILE "./fifo" 3 #include 4 #include 5 #include 6 #include 7 int main() 8 { 9 int fd=open(FIFO_FILE,O_WRONLY); 10 if(fd<0) 11 { 12 printf("文件打开失败!\n"); 13 return 1; 14 } 15 else if (fd>=0) 16 { 17 char buf[64]; 18 while(1) 19 { 20 printf("please Enter message# "); 21 fflush(stdout); 22 ssize_t s =read(0,buf,sizeof(buf)-1); 23 if(s>0) 24 { 25 buf[s]=0; 26 write(fd,buf,s); 27 } 28 } 29 } 30 return 0; 31 }
struct shmid_ds { struct ipc_perm shm_perm; /* operation perms / int shm_segsz; / size of segment (bytes) / __kernel_time_t shm_atime; / last attach time / 最后关联时间 __kernel_time_t shm_dtime; / last detach time / 最后去除关联时间 __kernel_time_t shm_ctime; / last change time /属性最后修改时间 __kernel_ipc_pid_t shm_cpid; / pid of creator / __kernel_ipc_pid_t shm_lpid; / pid of last operator / unsigned short shm_nattch; / no. of current attaches / unsigned short shm_unused; / compatibility */ void shm_unused2; / ditto - used by DIPC */ void shm_unused3; / unused */ };
首先要看到同一份资源,那么必须有标识操作系统上ipc资源的唯一性,就要用到ftok函数:
功能:用来创建共享内存 原型: int shmget(key_t key, size_t size, int shmflg); 参数: key:这个共享内存段名字。 size:共享内存大小。 shmflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的。 返回值:成功返回一个非负整数,即该共享内存段的标识码;失败返回-1。
1 #pragma once //防止头文件重复包含 2 #ifndef __ADD_H_ 3 #define __ADD_H__ 4 #endif 5 6 #define PATHNAME "/tmp" 7 #define PROJ_ID 0x6688 8 #define SIZE 4096 9
1 #include这里可以使用ipcs -m 查看共享内存: 如果要删除共享内存使用ipcrm -m shmid就可以:2 #include 3 #include"comm.h" 4 #include 5 #include 6 int main() 7 { 8 key_t k=ftok(PATHNAME,PROJ_ID); 9 printf("key=%d\n",k); 10 11 int shmid=shmget(k,SIZE,IPC_CREAT|IPC_EXCL); 12 if(shmid<0) 13 { 14 printf("创建共享内存失败!\n"); 15 } 16 return 0; 17 }
功能:将共享内存段连接到进程地址空间 原型: void shmat(int shmid, const void shmaddr, int shmflg); 参数: shmid: 共享内存标识 shmaddr:指定连接的地址 shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY 返回值:成功返回一个指针,指向共享内存第一个节;失败返回-1
1 #include2 #include 3 #include 4 #include"comm.h" 5 #include 6 #include 7 int main() 8 { 9 key_t k=ftok(PATHNAME,PROJ_ID); 10 printf("key=%p\n",k); 11 12 int shmid=shmget(k,SIZE,IPC_CREAT|0664); 13 if(shmid<0) 14 { 15 printf("创建共享内存失败!\n"); 16 return 0; 17 } 18 char* addr=(char*)shmat(shmid,NULL,0); 19 if(addr==NULL) 20 { 21 printf("关联失败!\n"); 22 return 0; 23 } 24 while(1) 25 { 26 printf("%s\n",(char*)addr); 27 sleep(1); 28 } 29 //shmdt(addr); 30 shmctl(shmid,IPC_RMID,NULL); 31 return 0; 32 }
功能:将共享内存段与当前进程脱离 原型: int shmdt(const void *shmaddr); 参数: shmaddr: 由shmat所返回的指针 返回值:成功返回0;失败返回-1 注意:将共享内存段与当前进程脱离不等于删除共享内存段
功能:用于控制共享内存 原型: int shmctl(int shmid, int cmd, struct shmid_ds *buf); 参数: shmid:由shmget返回的共享内存标识码 cmd:将要采取的动作(有三个可取值) buf:指向一个保存着共享内存的模式状态和访问权限的数据结构 返回值:成功返回0;失败返回-1
1 #include完整的客户端与服务端通信的代码 server.c:2 #include 3 #include 4 #include"comm.h" 5 #include 6 #include 7 int main() 8 { 9 key_t k=ftok(PATHNAME,PROJ_ID); 10 printf("key=%p\n",k); 11 12 int shmid=shmget(k,SIZE,IPC_CREAT|0664); 13 if(shmid<0) 14 { 15 printf("创建共享内存失败!\n"); 16 return 0; 17 } 18 char* addr=(char*)shmat(shmid,NULL,0); 19 if(addr==NULL) 20 { 21 printf("关联失败!\n"); 22 return 0; 23 } 24 while(1) 25 { 26 printf("%s\n",(char*)addr); 27 sleep(1); 28 } 29 //shmdt(addr); 30 shmctl(shmid,IPC_RMID,NULL); 31 return 0; 32 }
1 #include2 #include"head.h" 3 #include 4 #include 5 #include 6 #include 7 int main() 8 { 9 key_t k=ftok(PATHNAME,PROJ_ID); 10 printf("key=%d\n",k); 11 int shmid=shmget(k,SIZE,IPC_CREAT|IPC_EXCL|0666);//创建共享内存 12 13 if(shmid==-1) 14 { 15 printf("创建共享内存失败!\n"); 16 return 1; 17 } 18 printf("shmid=%d\n",shmid); 19 sleep(10); 20 21 char* str=(char*)shmat(shmid,NULL,0);//关联共享内存 22 // sleep(5); 23 while(1) 24 { 25 sleep(1); 26 printf("%s\n",str); 27 } 28 29 shmdt(str);//去除关联的共享内存 30 // sleep(5); 31 32 shmctl(shmid,IPC_RMID,NULL);//删除共享内存 33 sleep(5); 34 return 0; 35 }
client.c:
1 #include2 #include"head.h" 3 #include 4 #include 5 #include 6 #include 7 int main() 8 { 9 key_t k=ftok(PATHNAME,PROJ_ID); 10 printf("key=%p\n",k); 11 int shmid=shmget(k,SIZE,0);//创建共享内存 12 13 if(shmid==-1) 14 { 15 printf("创建共享内存失败!\n"); 16 return 1; 17 } 18 printf("shmid=%d\n",shmid); 19 // sleep(10); 20 21 char* str=(char*)shmat(shmid,NULL,0);//关联共享内存 22 // sleep(5); 23 24 25 char c='a'; 26 for(c;c<='z';c++) 27 { 28 str[c-'a']=c; 29 sleep(3); 30 } 31 shmdt(str);//去除关联的共享内存 32 sleep(5); 33 34 // shmctl(shmid,IPC_RMID,NULL);//删除共享内存 35 // sleep(10); 36 return 0; 37 }
makefile:
1 .PHONY:all 2 all:server client 3 client:client.c 4 gcc $^ -o $@ 5 server:server.c 6 gcc $^ -o $@ 7 .PHONY:clean 8 clean: 9 rm -f client server
head.h:
1 #pragma once 2 #define PATHNAME "/tmp" 3 #define PROJ_ID 0x6688 4 5 #define SIZE 4096ipcs 命令的扩展:
信号量主要用于同步和互斥的,下面先来看看什么是同步和互斥。
以上就是今天要讲的内容,本文仅仅简单介绍了Linux进程间通信中后两种方法的使用,而进程间通信提供了大量能使我们快速便捷地处理数据的函数和方法。我们务必掌握。到这里,进程间通信就结束了,后序将会有更重要的文章陆续更新,希望大家多多支持!另外如果上述有任何问题,请懂哥指教,不过没关系,主要是自己能坚持,更希望有一起学习的同学可以帮我指正,但是如果可以请温柔一点跟我讲,爱与和平是永远的主题,爱各位了。
转载地址:http://nulzi.baihongyu.com/