Linux下共享内存编程

利用共享内存(Share Memory)可以让我们在任意两个进程之间传递数据,而且也是相对容易实现的一种方法,在正常情况下,一个进程所使用的内存是不允许其它进程访问的,但是通过共享内存可以实现数据的共享。

使用共享内存用到的API函数有:

# include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

key_t ftok(const char *pathname, int proj_id)

其中pathname为当前进程的程序名,第二个参数为进程所开辟的第几个共享内存,返回一个key_t值,用于共享内存的获取使用。

int shmget(key_t shmkey, int shmsiz, int flag)

void *shmat(int shmid, char *shmaddr, int shmflag)

int shmdt(char *shmaddr)

shmget是用来创建或者指向一块共享内存的函数,其中shmkey是共享内存的标识符,如果父子关系的进程间通信的话,这个标识用IPC_PRIVATE替代,如果没有任何关系,可以使用ftok计算出来;Shmsiz是这块内存的大小;flag是这块内存的模式和权限标识(IPC_CREAT, IPC_ALLOC, IPC_EXCL,0666权限)。函数成功返回共享内存的shmid,否则返回-1表示失败。

Shmat用来允许进程访问共享内存的函数,其中shmid是共享内存的ID,shmaddr是共享内存起始位置,shmflag是本进程对内存操作模式,SHM_RDONLY是只读模式,成功返回共享内存的起始位置。

Shmdt与shmat相反,是用来禁止进程访问一块共享内存的函数。

int shmctl(int shmid, int cmd, struct shmid_ds *buf)

其中shmid是共享内存的ID,cmd是控制命令(IPC_STAT, IPC_SET, IPC_RMID),struct shmid_ds *buf是一个结构体指针,如果要改变共享内存的状态,使用它来指定,获得状态就存放在这个结构体中。

上述API函数的详细说明请使用man(男人)查看:

# man shmget | shmat | shmdt | shmctl

下面使用一个简单的例子说明如何使用共享内存。

// sharememcut.c 拷贝用户输入的字符串到共享内存中

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#include <stdio.h>

int main()

{

key_t shmkey;

int shmid, in_tmp;

char *head, *pos, in_data[4096], *in_ptr;

// Create share memory KEY

shmkey = ftok("sharememcut", 1);

// Get the share memory ID

shmid = shmget(shmkey, sizeof(in_data), IPC_CREAT | 0666);

// Allow the process to access share memory, and get the address

head = pos = shmat(shmid, 0, 0);

in_ptr = in_data;

// Receive the character from stdin, ‘q’ to quit

while ((in_tmp = getchar()) != ‘q’) {

*in_ptr = in_tmp;

in_ptr++;

}

*in_ptr = ‘\0’;

in_ptr = in_data;

// Cut the data into share memory

while (*in_ptr != ‘\0’) {

*pos++ = *in_ptr++;

}

// Prohabit the process to access share memory

shmdt(head);

return 0;

}

# gcc -o sharememcut sharememcut.c 编译sharememcut.c

# ./sharememcut 执行sharememcut创建共享内存

# ipcs -m | grep 4096 查看创建的共享内存

0x01068288 348848145 root 666 4096 0

// sharemempaste.c 将共享内存的内容显示在屏幕上并且删除共享内存

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#include <stdio.h>

int main()

{

key_t shmkey;

int shmid;

char *head, *pos, out_data[4096], *out_ptr;

// Create share memory KEY

shmkey = ftok("sharememcut", 1);

// Get the share memory ID

shmid = shmget(shmkey, sizeof(out_data), 0666);

if (shmid == -1)

return -1;

// Allow the process to access share memory, and get the address

head = pos = shmat(shmid, 0, 0);

out_ptr = out_data;

// Get the data from share memory

while (*pos != ‘\0’) {

*out_ptr++ = *pos++;

}

*out_ptr = ‘\0’;

// Output the data into stdout

printf("%s\n", out_data);

fflush(stdout);

// Prohabit the process to access share memory

shmdt(head);

// Delete the share memory

shmctl(shmid, IPC_RMID, NULL);

return 0;

}

# gcc -o sharemempaste sharemempaste.c 编译sharemempaste.c

# ./sharemempaste 执行程序显示共享内存的内容

陷阱请参考:http://www.ibm.com/developerworks/cn/aix/library/au-cn-sharemem/不求与人相比,但求超越自己,要哭就哭出激动的泪水,要笑就笑出成长的性格。

Linux下共享内存编程

相关文章:

你感兴趣的文章:

标签云: