1.进程通信
进程通信一般分为以下6类
- 共享内存(shared memory):多个进程可以访问同一块内存空间。
- 套接字(socket):可用于不同计算机之间的进程间通信。
- 信号量(semaphore):用于进程之间对共享资源进行加锁。
- 信号(signal):信号用于通知其它进程有某种事件发生。
- 消息队列(message):进程可以向队列中添加消息,其它的进程则可以读取队列中的消息。
- 管道(pipe):包括无名管道,命名管道,无名管道可用于具有父进程和子进程之间的通信。命名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。
2.共享内存
共享内存(Shared Memory):允许多个进程访问同一个内存空间,是在多个进程之间共享和传递数据最高效的方式。操作系统将不同进程之间共享内存安排为同一段物理内存,进程可以将共享内存连接到它们自己的地址空间中,如果某个进程修改了共享内存中的数据,其它的进程读到的数据也将会改变。
弊端:共享内存没提供同步机制,通常需要与信号量搭配使用。
3.共享内存api函数
在Linux操作系统中,提供了一组函数用于操作共享内存。但是需要包含以下库函数
1 2
| #include <sys/ipc.h> #include <sys/shm.h>
|
1.shmget函数:创建共享内存
用于获取或者创建共享内存
1 2 3 4 5 6 7 8 9
| int shmget(key_t key, size_t size, int shmflg);
|
2.shmat函数:挂接共享内存
用于把共享内存连接到当前进程的地址空间
1 2 3 4 5 6 7 8
| void *shmat(int shm_id, const void *shm_addr, int shmflg);
|
3.shmdt函数:去关联共享内存
用于将共享内存从当前进程中分离,相当于shmat函数的反操作。
1 2 3 4 5 6
| int shmdt(const void *shmaddr);
|
4.shmctl函数:销毁共享内存
用于删除共享内存
1 2 3 4 5 6 7 8
| int shmctl(int shm_id, int command, struct shmid_ds *buf);
|
4.共享内存使用Demo
1.serve.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
|
#include <stdio.h> #include <sys/ipc.h> #include <sys/shm.h> #include <errno.h> #include <unistd.h> #include <string.h>
#define SHM_SERIAL_NUM 0x2020 #define SHM_SIZE 2048 void free_shm_from_driver(void * share_memory,int shm_id) { if(-1 == shmdt(share_memory)){ printf("shmdt(share_memory) fail! error= %d",errno); } if(-1 == shmctl(shm_id,IPC_RMID,0)){ printf("shmdt(share_memory) fail! error= %d",errno); } } int main() { int i=0; int shm_id = shmget((key_t)SHM_SERIAL_NUM,SHM_SIZE,0660|IPC_CREAT); if(shm_id == -1){ printf("Share memory create fail! errno=%d",errno); return -1; } char* p_str=shmat(shm_id,NULL,0); if((void *)-1 == p_str){ printf("shmat(shm_id) fail! errno=%d",errno); } while(i<25){ snprintf(p_str,500,"This is in serve process pid= %d,i=%d\n",getpid(),++i); printf("%s\n",p_str); sleep(2); } return 0; }
|
2.client.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
#include <stdio.h> #include <sys/ipc.h> #include <sys/shm.h> #include <errno.h> #include <string.h> #include <unistd.h>
#define SHM_SERIAL_NUM 0x2020 #define SHM_SIZE 2048
void free_shm_from_driver(void * share_memory,int shm_id) { if(-1 == shmdt(share_memory)){ printf("shmdt(share_memory) fail! error= %d\n",errno); } if(-1 == shmctl(shm_id,IPC_RMID,0)){ printf("shmdt(share_memory) fail! error= %d\n",errno); } }
int main() { int i=0; int shm_id = shmget((key_t)SHM_SERIAL_NUM,SHM_SIZE,0660|IPC_CREAT); if(shm_id == -1){ printf("Share memory create fail! errno=%d",errno); return -1; } char* p_str=shmat(shm_id,NULL,0); if((void *)-1 == p_str){ printf("shmat(shm_id) fail! errno=%d",errno); } while(i<100){ printf("%s\n",p_str); printf("%s%d\n","This is in client process pid=",getpid()); sleep(1); ++i; } return 0; }
|
5.附录
linux 下查看共享内存命令 ipcs -m