shmget函数原型为:
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg); key: 函数ftok返回值。或者IPC_PRIVATE ,当使用IPC_PRIVATE时。最好两个进程空间是共享的,比方父子进程,否则当前进程产生的共享内存标识(返回值)。在还有一个进程里面不易得到。
shmflg:读写权限值组合。
IPC_CREAT(创建新的共享内存)或IPC_CREAT|IPC_EXCL(当将要创建的共享内存已经存在时,再试图创建将返回EEXIST)。
事实上IPC_CREAT和IPC_EXCL的组合和open函数的O_CREAT和O_EXCL组合类似。
函数返回共享内存区的标识。
shmxxx函数操作共享内存将使用该函数返回值。
该函数类似posix共享内存shm_open函数功能。
当shmget创建或打开一个共享内存区后。须要使用函数shmat来将该片共享内存连接到当前进程空间中来,当某一进程使用完共享内存后,使用函数shmdt断开和共享内存的链接。
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr); shmid:是函数shmget函数返回的共享内存标识符。 #include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf);int sln_shm_get(char *shm_file, void **mem, int mem_len)
{
int shmid;
key_t key;
if (NULL == fopen(shm_file, "w+")) {
printf("fopen: %s\n", strerror(errno));
return -1;
}
key = ftok(shm_file, 0);
if (key < 0) {
printf("ftok: %s\n", strerror(errno));
return -1;
}
shmid = shmget(key, mem_len, IPC_CREAT);
if (shmid < 0) {
printf("shmget: %s\n", strerror(errno));
return -1;
}
*mem = (void *)shmat(shmid, NULL, 0);
if ((void *)-1 == *mem) {
printf("shmat: %s\n", strerror(errno));
return -1;
}
return shmid;
}
int main(int argc, const char *argv[])
{
char *shm_file = NULL;
char *shm_buf = NULL;
int shmid;
shmid = sln_shm_get(SHM_IPC_FILENAME, (void **)&shm_buf, SHM_IPC_MAX_LEN);
if (shmid < 0) {
return -1;
}
snprintf(shm_buf, SHM_IPC_MAX_LEN, "Hello system V shaare memory IPC! this is write by server.");
sleep(15);
printf("System V server delete share memory segment!\n");
//shmdt(shm_buf);
shmctl(shmid, IPC_RMID, NULL); //server在15秒之后destroy该片共享内存。此时客户进程将获取不到共享内存的内容
return 0;
}
client process:
int sln_shm_get(char *shm_file, void **mem, int mem_len)
{
int shmid;
key_t key;
key = ftok(shm_file, 0);
if (key < 0) {
printf("ftok: %s\n", strerror(errno));
return -1;
}
shmid = shmget(key, mem_len, IPC_CREAT);
if (shmid < 0) {
printf("shmget: %s\n", strerror(errno));
return -1;
}
*mem = (void *)shmat(shmid, NULL, 0);
if ((void *)-1 == *mem) {
printf("shmat: %s\n", strerror(errno));
return -1;
}
return shmid;
}
int main(int argc, const char *argv[])
{
char *shm_buf = NULL;
int i;
if (sln_shm_get(SHM_IPC_FILENAME, (void **)&shm_buf, SHM_IPC_MAX_LEN) < 0) {
return -1;
}
printf("ipc client get: %s\n", shm_buf);
return 0;
}
# ipcs ------ Message Queues -------- key msqid owner perms used-bytes messages ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x0010a797 131072 root 0 4096 1 ------ Semaphore Arrays -------- key semid owner perms nsems
# ./client ipc client get: Hello system V shaare memory IPC! this is write by server. #
# ipcs ------ Message Queues -------- key msqid owner perms used-bytes messages ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status ------ Semaphore Arrays -------- key semid owner perms nsems 此时共享内存已经不在了,但文件依旧存在。# ./client ipc client get: #
# cat /proc/sys/kernel/shmmax 33554432 #
相同的,system V共享内存大多数时候也须要在多进程之间同步,system V 能够使用自己的信号量来实现,具体细节将在后面同步相关专栏具体解说。
本节源代码下载:
版权声明:本文博客原创文章,博客,未经同意,不得转载。
阐述linux IPC(五岁以下儿童):system V共享内存
原文:http://www.cnblogs.com/mengfanrong/p/4712512.html