Linux进程间的通信~共享内存

共享内存

(一)什么是共享内存

顾名思义,共享内存就是两个不相关的进程之间利用同一块内存进行数据传输。但是由于共享内存并没有提供同步机制,所以再利用共享内存时需要其他的机制来同步对该内存的访问。常用的是信号量。

(二)共享内存的实现

#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
void shmat(int shm_id, const void *shm_addr, int shmflag);
int shmctl(int shm_id, int cmd, struct shmid_ds *buf);
int shmdt(const void *shm_addr);

其中,利用shmget函数来创建共享内存。返回一个共享内存标识符,该标识符用于后续的共享内存函数。当第一次创建共享内存时,它不能被任何进程访问,想要启用对该内存的访问,就需要利用shmat函数将其连接到该进程的地址空间上。其返回的就是该内存的起始地址,如果失败会返回-1。那么就可以根据指针来对内存进行操作了。
操作完成后,使用shmdt函数将内存分离,成功返回0,失败返回-1。该操作只会分离进程与内存,并不会释放该内存。
最后一个函数是共享内存的控制函数shmctl。它相比于信号量的控制函数要简单一些。
其中,控制命令有三种,分别是IPC_STAT、IPC_SET和IPC_RMID。
IPC_STAT是利用shmid_ds 结构获取当前共享内存的状态
IPC_SET,当进程有足够的权限,则利用shmid_ds结构设置当前共享内存的状态。
IPC_RMID就是删除指定的共享内存。当然要在所有进程分离该内存之后,否则会发生不可控制的事情。

共享内存的示例代码

由于需要进程同步,所以本代码包含了信号量的内容。

信号量的介绍:Linux进程间的通信~信号量。

代码如下

//  Shm1
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>

#include <sys/shm.h>
#include "sem.h"

int main()
{
	int shmid = shmget((key_t) 1234, 128, IPC_CREAT | 0664); //共享内存
	assert(shmid != -1);

	int semVal = 1;
	int semid = SemGet(1000, &semVal, 1);

	char *ptr = (char*)shmat(shmid, NULL, 0);
	assert(ptr != (char*)-1);

	while(1)
	{
		int index = 0;
		SemP(semid, &index, 1);
		printf("please input: ");
		fgets(ptr, 128, stdin);

		SemV(semid, &index, 1);

		if(strncmp(ptr, "end", 3) == 0)
		{
			break;
		}
	}

	shmdt(ptr);
}
// shm2

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>

#include <sys/shm.h>

#include "sem.h"

int main()
{
	int shmid = shmget((key_t) 1234, 128, IPC_CREAT | 0664); //共享内存
	assert(-1 != shmid);

	int semVal = 1;            
	int semid = SemGet(1000, &semVal, 1);

	char *ptr = (char *)shmat(shmid, NULL, 0);
	assert((char*)-1 != ptr);

	while(1)
	{
		int index = 0;
		SemP(semid, &index, 1);

		if(strncmp(ptr, "end", 3) == 0)
		{
			break;
		}

		printf("lenth = %d :  %s", strlen(ptr) - 1, ptr);
		sleep(2);
		SemV(semid, &index, 1);
	}

	shmdt(ptr);
}

这两段代码实现了 shm1向共享内存中写入数据,shm2从共享内存中读出数据并且显示的功能。涉及到了三个函数,并没有使用shmctl函数。

猜你喜欢

转载自blog.csdn.net/ichliebecamb/article/details/89041193