linuxC多进程通讯---POSIX共享内存

相关的API函数

•int shm_open (const char *name, int oflag, mode_t mode);
•int shm_unlink (const char *name);
•int ftruncate (int fd, off_t length);
•int fstat (int fd, struct stat *buf);
•void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
•int munmap (void *addr, size_t length);

在这里插入图片描述

ftruncate

函数功能:改变文件大小

相关函数:open、truncate
表头文件:#include <unistd.h>
函数原型:int ftruncate(int fd, off_t length)
函数说明:ftruncate()会将参数fd指定的文件大小改为参数length指定的大小。参数fd为已打开的文件描述词,而且必须是以写入模式打开的文件。如果原来的文件件大小比参数length大,则超过的部分会被删去
返 回 值:0、-1
错误原因:errno
EBADF 参数fd文件描述词为无效的或该文件已关闭
EINVAL 参数fd为一socket并非文件,或是该文件并非以写入模式打开

munmap

函数说明 munmap()用来取消参数start所指的映射内存起始地址,参数length则是欲取消的内存大小。当进程结束或利用exec相关函数来执行其他程序时,映射内存会自动解除,但关闭对应的文件描述符时不会解除映射。

munmap(解除内存映射)
相关函数 mmap
表头文件 #include<unistd.h>
#include<sys/mman.h>
定义函数 int munmap(void *start,size_t length);
函数说明 munmap()用来取消参数start所指的映射内存起始地址,参数length则是欲取消的内存大小。当进程结束或利用exec相关函数来执行其他程序时,映射内存会自动解除,但关闭对应的文件描述符时不会解除映射。
返回值 如果解除映射成功则返回0,否则返回-1,错误原因存于errno中错误代码EINVAL

简单的共享内存读写示例

read

#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#define SHM_NAME "/shm"

int main (void)
{
	int shm_fd;
	shm_fd = shm_open (SHM_NAME, O_RDWR | O_CREAT, 0);
	if (shm_fd < 0)
	{
		perror ("shm_open");
		return -1;
	}
	ftruncate (shm_fd, 8192);
	struct stat filestat;
	fstat (shm_fd, &filestat);
    printf ("st_size: %ld\n", filestat.st_size);
	char *shm_ptr;
	shm_ptr = (char*)mmap (NULL, filestat.st_size, \
            PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0);
	close (shm_fd);
	printf ("pid %d: %s\n", getpid(), shm_ptr);
    munmap (shm_ptr, filestat.st_size);
    shm_unlink (SHM_NAME);
	return 0;
}

write

#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>

#define SHM_NAME "/shm"

int main (void)
{
	int shm_fd;
	shm_fd = shm_open (SHM_NAME, O_RDWR | O_CREAT, 0666);
	if (shm_fd < 0)
	{
		perror ("shm_open");
		return -1;
	}

	ftruncate (shm_fd, 8192);
    struct stat filestat;
	fstat (shm_fd, &filestat);
    printf ("st_size: %ld\n", filestat.st_size);

	char *shm_ptr;
	shm_ptr = (char*)mmap (NULL, filestat.st_size, \
              PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0);
	close (shm_fd);

	char buf[] = "hello world";
	memmove (shm_ptr, buf, sizeof (buf));
	printf ("pid %d: %s\n", getpid(), shm_ptr);
    munmap (shm_ptr, filestat.st_size);
	return 0;
}

信号量和共享内存 使用示例

write

#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>

#define SHM_NAME "/memmap"
#define SEM_NAME "/memmap_sem"

int main (void)
{
	int shm_fd;
	sem_t *sem;
	shm_fd = shm_open (SHM_NAME, O_RDWR | O_CREAT, 0666);
	sem = sem_open (SEM_NAME, O_CREAT, 0666, 0);
	if (shm_fd < 0 || sem == SEM_FAILED)
	{
		perror ("open");
		return -1;
	}
    ftruncate (shm_fd, 8192);
	struct stat filestat;
	fstat (shm_fd, &filestat);
    printf ("st_size: %ld\n", filestat.st_size);
	char *shm_ptr;
	shm_ptr = (char*)mmap (NULL, filestat.st_size,  \
                PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0);
	close (shm_fd);

	char msg[] = "hello world";
	memmove (shm_ptr, msg, sizeof (msg));
	printf ("pid %d: %s\n", getpid(), shm_ptr);
    
	sem_post (sem);
	sem_close (sem);
    sleep (5);
    munmap (shm_ptr, 8192);

	return 0;
}

read

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <semaphore.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#define SHM_NAME "/memmap"
#define SEM_NAME "/memmap_sem"

int main (void)
{
	int shm_fd;
	sem_t *sem;
	shm_fd = shm_open (SHM_NAME, O_RDWR|O_CREAT, 0666);
	sem = sem_open (SEM_NAME, 0);
	if (shm_fd < 0 || sem == SEM_FAILED)
	{
		perror ("open");
		return -1;
	}
    ftruncate (shm_fd, 8192);
	struct stat filestat;
	fstat (shm_fd, &filestat);
    printf ("st_size: %ld\n", filestat.st_size);
	char *shm_ptr;
	shm_ptr = (char*)mmap (NULL, filestat.st_size, PROT_READ|PROT_WRITE, \
							MAP_SHARED, shm_fd, 0);
    if (shm_ptr ==(void*)-1)
    {
        perror ("mmap");
        exit (-1);
    }
	close (shm_fd);
	sem_wait (sem);
	printf ("pid %d: %s\n", getpid(), shm_ptr);
	sem_close (sem);
    munmap (shm_ptr, 8192);
    shm_unlink (SHM_NAME);
    sem_unlink (SEM_NAME);
	return 0;
}

发布了349 篇原创文章 · 获赞 6 · 访问量 9740

猜你喜欢

转载自blog.csdn.net/qq_23929673/article/details/100173384