shm = shmat(shmid, 0, 0);
//设置共享内存
shared = (struct shared_use_st*)shm;
shared->written = 0;
//访问共享内存
while(1){
if(shared->written != 0) {
printf(“You wrote: %s”, shared->text);
if(strncmp(shared->text, “end”, 3) == 0)
break;
}}
//把共享内存从当前进程中分离
if(shmdt(shm) == -1) { }
//删除共享内存
if(shmctl(shmid, IPC_RMID, 0) == -1) { }
exit(EXIT_SUCCESS);
}
写进程
int main()
{
void *shm = NULL;
struct shared_use_st *shared = NULL;
char buffer[BUFSIZ + 1];//用于保存输入的文本
int shmid;
//创建共享内存
shmid = shmget((key_t) 12345, sizeof(struct shared_use_st), 0666|IPC_CREAT);
//将共享内存连接到当前进程的地址空间
shm = shmat(shmid, (void*)0, 0);
printf(“Memory attached at %X\n”, (int)shm);
//设置共享内存
shared = (struct shared_use_st*)shm;
while(1)//向共享内存中写数据
{
//数据还没有被读取,则等待数据被读取,不能向共享内存中写入文本
while(shared->written == 1)
{
sleep(1);
}
//向共享内存中写入数据
fgets(buffer, BUFSIZ, stdin);
strncpy(shared->text, buffer, TEXT_SZ);
shared->written = 1;
if(strncmp(buffer, “end”, 3) == 0)
running = 0;
}
//把共享内存从当前进程中分离
if(shmdt(shm) == -1) { }
sleep(2);
exit(EXIT_SUCCESS);
}
可以看到,Linux共享内存通信效率非常高,进程间不需要传递数据,便可以直接访问,缺点也很明显,Linux共享内存没有提供同步的机制,在使用时,要借助其他的手段来处理进程间同步。Anroid本身在核心态是支持System V的功能,但是bionic库删除了glibc的shmget等函数,使得android无法采用shmget的方式实现有名共享内存,当然,它也没想着用那个,Android在此基础上,创建了自己的匿名共享内存方式。
Android的匿名共享内存
==============
Android可以使用Linux的一切IPC通信方式,包括共享内存,不过Android主要使用的方式是匿名共享内存Ashmem(Anonymous Shared Memory),跟原生的不太一样,比如它在自己的驱动中添加了互斥锁,另外通过fd的传递来实现共享内存的传递。MemoryFile是Android为匿名共享内存而封装的一个对象,这里通过使用MemoryFile来分析,Android中如何利用共享内存来实现大数据传递,同时MemoryFile也是进程间大数据传递的一个手段,开发的时候可以使用:
IMemoryAidlInterface.aidl
package com.snail.labaffinity;
import android.os.ParcelFileDescriptor;
interface IMemoryAidlInterface {
ParcelFileDescriptor getParcelFileDescriptor();
}
MemoryFetchService
public class MemoryFetchService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new MemoryFetchStub();
}
static class MemoryFetchStub extends IMemoryAidlInterface.Stub {
@Override
public ParcelFileDescriptor getParcelFileDescriptor() throws RemoteException {
MemoryFile memoryFile = null;
try {
memoryFile = new MemoryFile(“te