共享内存。linux进程之间通信的一种方式。先说说优缺点吧。
共享内存,顾名思义,就是一块内存,大家都可以用。
优点:操作方便。直接访问内存,效率高。不需要进程有父子关系等等
缺点:需要自己同步控制。
关于linux的任何函数都可以通过命令man order,查看相关帮助。想要仔细看这些函数的相关帮助,请亲自操作,这是最好的方法。
涉及的函数:
注:这一系列函数都是以shm开头(share memory)。
头文件 :
#include <sys/ipc.h>
#include <sys/shm.h>
1. int shmget(key_t key, size_t size, int shmflg);
这个函数的功能就是用来分配要共享的内存。但是并不是分配好就能用的。要想使用,请看下一个函数。
参数:
key_t key :关键码,可以自己随意定义,一个关键码对应一块共享内存。其他地方要想获取这块内存,需要知道这个key。
size_t size:要共享的内存的大小。相当于我们malloc时的参数。
int shmflg :这个标志是权限,一般可以设置为 0666|IPC_CREAT.
返回值:
成功返回共享内存的id。
失败返回-1,同时会设置errno。
2. void *shmat(int shmid, const void *shmaddr, int shmflg);
用来启动可分享的内存,并且把这段内存链接到本程序的地址空间中。
成功返回可分享内存的首地址,失败返回(void*)-1;
3. int shmdt(const void *shmaddr);
用来取消分享内存与本程序的关联。并不是释放这段分享的内存空间。
成功返回0,失败返回-1。
4. int shmctl(int shmid, int cmd, struct shmid_ds *buf);
用来控制共享内存。
struct shmid_ds {
struct ipc_perm shm_perm; /* Ownership and permissions */
size_t shm_segsz; /* Size of segment (bytes) */
time_t shm_atime; /* Last attach time */
time_t shm_dtime; /* Last detach time */
time_t shm_ctime; /* Last change time */
pid_t shm_cpid; /* PID of creator */
pid_t shm_lpid; /* PID of last shmat(2)/shmdt(2) */
shmatt_t shm_nattch; /* No. of current attaches */
...
};
下面是一些代码。每隔1秒去设置一下共享内存的内容。
<span style="font-size:14px;">#include <stdio.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <string.h>
int main()
{
int shmid;
void* mem;
shmid = shmget(8889, 4, 0666|IPC_CREAT);
if (shmid == -1)
{
printf("shmget err!\n");
return -1;
}
mem = shmat(shmid, 0, 0);
if (mem == (void*)-1)
{
printf("shmat err!\n");
return -2;
}
int i=0;
for (; i<20 ; i++)
{
*(int*)mem = i;
printf("shm set:%d\n", i);
sleep(1);
}
if (-1 == shmdt(mem))
{
printf("shmdt err!\n");
return -3;
}
return 0;
}</span>
另一个进程,每隔1秒读取一下共享内存的内容。
<span style="font-size:14px;">#include <stdio.h>
#include <stdlib.h>
#include <sys/shm.h>
int main()
{
int shmid ;
void* mem;
shmid = shmget(8889, 4, 0666|IPC_CREAT);
if (shmid == -1)
{
printf("shmget err!\n");
return -1;
}
mem = shmat(shmid, 0, 0);
if (mem == (void*)-1)
{
printf("shmat err!\n");
return -2;
}
int i = 0;
for(;i<20;i++)
{
printf("shm:%d\n",*(int*)mem);
sleep(1);
}
if (-1 == shmdt(mem))
{
printf("shmdt err!\n");
return -3;
}
if (shmctl(shmid, IPC_RMID, 0) == -1)
{
printf("shmctl(shmid, IPC_RMID, 0) err!\n");
return -4;
}
return 0;
}</span>
同时运行两个程序。结果如图;
可以看出,由于没有同步控制。s1一开始输出了两个0。也是属于正常情况。这也是共享内存的缺点,需要我们自己同步。下一篇,学习信号量与共享内存同时使用。自己来同步。。
如有问题,请斧正。感激不尽。
谢谢!