今天开共享内存总结:
在Linux进程间通信的方式中,共享内存是一种最快的IPC方式。因此,共享内存用于实现进程间大量的数据传输,共享内存的话,会在内存中单独开辟一段内存空间,这段内存空间有自己特有的数据结构,包括访问权限、大小和最近访问的时间等。
优点:(引用https://www.cnblogs.com/readlearn/p/10806417.html)
上图可知,普通进程通信复制四次,共享内存两次。
使用头文件:
#include <sys/shm.h>
int shmget(key_t key, int size, int flag) ;
key为程序自己提供,为共享内存命名
返回一个标识符,失败返回-1,通过返回值,不同进程可以共享内存。flg为权限标志。
void *shmat(int shmid, void *addr, int flag); 连接共享内存与虚拟内存,id为get返回值,返回值为地址。
int shmdt(const void *shmaddr); 为分离操作,并不删除。
实例关键步骤:
写
int shmid;
shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666| IPC_CREAT) ; //创建
//判断是否成功
void *shared_memory = (void *)0;
shared_memory = shmat(shmid, (void *)0, 0); //获得内存地址
//判断返回值
struct shared_use_st *shared_stuff;
shared_stuff = (struct shared use_st *)shared_memory;//自定义的结构
while(1)
{
while(shared_stuff->written == 1) {
sleep(l);
printf(”waiting for client ...\n”);
}
fgets (buffer, BUFSIZ, stdin);
strncpy(shared_stuff >text, buffer, TEXT_SZ);
shared_stuff->written = 1;
if (strncmp(buffer ,”end" , 3) == 0)
{
//此处写退出
}//同步机制,读写
}
/
读
shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666 | IPC_CREAT);
void *shared_memory = (void *)0;
shared_memory = shmat(shmid, (void *)0, 0);
printf(”Memory attached at %X\n”, ( long)shared_memory) ;
struct shared_use_st *shared_stuff;
shared_stuff = (struct shared_use st *)shared_memory;
shared_stuff->written = 0;
while(running)
{
if (shared_stuff->written){
printf(”You wrote: % S” , shared_stuff->text);
sleep( rand ()&4 ) ;
shared_stuff->written = O;
if ( strn_cmp ( shared_stuff->text, "end",3)==0)
{
running = O;
}
}
}
缺点:
事实上,这个程序是不安全的,当有多个程序同时向共享内存中读写数据时,问题就会出现。 可能你会认为,可以改变一下written的使用方式来解决问题。 例如,只有当written为0时进程才可以向共享内存写人数据,而只有当written不为0时才能对其进行读取,同时把written进行加1 操作,读取完后进行减l 操作,这就有点像文件锁中的读写锁的功能。
但实际上这都不是原子操作,所以这种做法是不可行的。 试想当written为0时,如果有两个进程同时访问共享内存,它们就会发现written为0,于是两个进程都对其进行写操作,这种操作显然不行。 当written的值为1 时,有两个进程同时对共享内存进行读操作时也是如此,当这两个进程都读取完时,written的值就变成了-1。可用信号量。