扁平化网站设计趋势,湖南对外建设集团网站,奥鹏网页设计与网站建设,铁岭网站建设移动网站1、前言
1.1 定义
POSIX共享内存是一种在UNIX和类UNIX系统上可用的进程间通信机制。它允许多个进程共享同一块内存区域#xff0c;从而可以在这块共享内存上进行读写操作。
1.2 应用场景
POSIX共享内存适用于需要高效地进行大量数据交换的场景#xff0c;比如多个进程需要…1、前言
1.1 定义
POSIX共享内存是一种在UNIX和类UNIX系统上可用的进程间通信机制。它允许多个进程共享同一块内存区域从而可以在这块共享内存上进行读写操作。
1.2 应用场景
POSIX共享内存适用于需要高效地进行大量数据交换的场景比如多个进程需要共享大型数据集合或缓存。它可以提供比其他进程间通信方式更快的数据传输速度
1.3 优缺点
1.3.1 优点
高效性共享内存允许多个进程直接访问同一块内存因此数据传输速度更快。灵活性由于共享内存是直接映射到进程的地址空间因此对数据的访问更加灵活。
1.3.2 缺点
同步问题需要额外的同步机制来确保多个进程对共享内存的访问是安全的。通信复杂性共享内存通常需要与其他进程间通信方式如信号量、互斥量等结合使用。
2、常用接口
2.1 shm_open函数
创建或打开一个POSIX共享内存对象。
int shm_open(const char *name, int oflag, mode_t mode);
参数
name共享内存对象的名称以斜杠开头类似于文件路径。oflag打开标志可以使用 O_CREAT 表示创建共享内存对象O_RDWR 表示读写模式等。mode创建共享内存对象时的权限模式。
返回值
成功返回一个非负整数表示共享内存对象的文件描述符。失败返回 -1并设置 errno 以指示错误原因。
2.2 ftruncate函数
设置共享内存对象的大小。
int ftruncate(int fd, off_t length);参数
fd共享内存对象的文件描述符。length要设置的共享内存大小。
返回值
成功返回 0。失败返回 -1并设置 errno 以指示错误原因。
2.3 mmap函数
将共享内存对象映射到进程的地址空间。
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);参数
addr指定映射的地址通常为0表示由系统选择合适的地址。length映射的长度。prot映射的保护模式如 PROT_READ 和 PROT_WRITE。flags映射的标志如 MAP_SHARED 表示共享映射。fd共享内存对象的文件描述符。offset共享内存对象的偏移量。
返回值
成功返回映射区的起始地址。失败返回 MAP_FAILED并设置 errno 以指示错误原因。
2.4 munmap函数
解除共享内存的映射。
int munmap(void *addr, size_t length);参数
addr要解除映射的地址。length映射的长度。
返回值
成功返回 0。失败返回 -1并设置 errno 以指示错误原因。
2.5 shm_unlink函数
删除共享内存对象。
int shm_unlink(const char *name);
参数
name共享内存对象的名称。
返回值
成功返回 0。失败返回 -1并设置 errno 以指示错误原因。
3、编程测试
3.1 共享内存简单测试
测试代码如下代码编译需要加-lrt -pthread
#include stdio.h
#include stdlib.h
#include string.h
#include unistd.h
#include sys/mman.h
#include sys/stat.h
#include fcntl.h
#include time.h// 打印时分秒的宏
#define PRINT_MIN_SEC do { \time_t t time(NULL); \struct tm *tm_ptr localtime(t); \printf(%02d:%02d:%02d:, tm_ptr-tm_hour, tm_ptr-tm_min, tm_ptr-tm_sec);\} while (0);printf#define SHM_NAME /example_shm
#define SHM_SIZE 1024void parent_process();
void child_process();int main()
{pid_t pid fork();if (pid 0) {child_process();} else if (pid 0) {parent_process();} else {perror(fork failed);exit(EXIT_FAILURE);}return 0;
}void parent_process()
{PRINT_MIN_SEC(Parent start!\n);int shm_fd shm_open(SHM_NAME, O_CREAT | O_RDWR, 0666);if (shm_fd -1) {perror(shm_open failed);exit(EXIT_FAILURE);}ftruncate(shm_fd, SHM_SIZE);char *ptr mmap(0, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);if (ptr MAP_FAILED) {perror(mmap failed);exit(EXIT_FAILURE);}bzero(ptr, SHM_SIZE);strcpy(ptr, Parent Write Data);sleep(2); // 等待子进程读取共享内存中的数据PRINT_MIN_SEC(Parent read from shared memory: %s\n, ptr);munmap(ptr, SHM_SIZE);close(shm_fd);shm_unlink(SHM_NAME);
}void child_process()
{PRINT_MIN_SEC(Child start!\n);sleep(1); // 等待父进程创建共享内存并写入数据到共享内存int shm_fd shm_open(SHM_NAME, O_RDWR, 0666);if (shm_fd -1) {perror(shm_open failed);exit(EXIT_FAILURE);}char *ptr mmap(0, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);if (ptr MAP_FAILED) {perror(mmap failed);exit(EXIT_FAILURE);}PRINT_MIN_SEC(Child read from shared memory: %s\n, ptr);bzero(ptr, SHM_SIZE);strcpy(ptr, Child Write Data);munmap(ptr, SHM_SIZE);close(shm_fd);
}
通过父子间进程读写共享内存的时间不一致来实现进程通信测试结果如下 3.2 共享内存配合信号量使用测试
测试代码如下代码编译需要加-lrt -pthread
#include stdio.h
#include stdlib.h
#include string.h
#include unistd.h
#include sys/mman.h
#include sys/stat.h
#include fcntl.h
#include time.h
#include semaphore.h// 打印时分秒的宏
#define PRINT_MIN_SEC do { \time_t t time(NULL); \struct tm *tm_ptr localtime(t); \printf(%02d:%02d:%02d:, tm_ptr-tm_hour, tm_ptr-tm_min, tm_ptr-tm_sec);\} while (0);printf#define SHM_NAME /example_shm
#define SHM_SIZE 1024void parent_process();
void child_process();// 打印当前信号量的值
void printfValue(sem_t *sem)
{// 打印当前值int value;sem_getvalue(sem, value);PRINT_MIN_SEC(Current value of semaphore: %d\n, value);
}int main()
{sem_t *mutex sem_open(/mysemaphore, O_CREAT, 0644, 0); pid_t pid fork();if (pid 0) {child_process(mutex);} else if (pid 0) {parent_process(mutex);} else {perror(fork failed);exit(EXIT_FAILURE);}return 0;
}void parent_process(sem_t * mutex)
{int SendNum 0;char SendData[32] {0};PRINT_MIN_SEC(Parent start!\n);printfValue(mutex);int shm_fd shm_open(SHM_NAME, O_CREAT | O_RDWR, 0666);if (shm_fd -1) {perror(shm_open failed);exit(EXIT_FAILURE);}ftruncate(shm_fd, SHM_SIZE);char *ptr mmap(0, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);if (ptr MAP_FAILED) {perror(mmap failed);exit(EXIT_FAILURE);}while(1){sprintf(SendData, Parent Write Data-%d\n, SendNum);SendNum;strcpy(ptr, SendData);sem_post(mutex);sleep(2);}PRINT_MIN_SEC(Parent read from shared memory: %s\n, ptr);munmap(ptr, SHM_SIZE);close(shm_fd);shm_unlink(SHM_NAME);
}void child_process(sem_t * mutex)
{PRINT_MIN_SEC(Child start!\n);printfValue(mutex);sleep(1); // 等待父进程创建共享内存并写入数据到共享内存int shm_fd shm_open(SHM_NAME, O_RDWR, 0666);if (shm_fd -1) {perror(shm_open failed);exit(EXIT_FAILURE);}char *ptr mmap(0, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);if (ptr MAP_FAILED) {perror(mmap failed);exit(EXIT_FAILURE);}while(1){sem_wait(mutex);PRINT_MIN_SEC(Child read from shared memory: %s\n, ptr);}munmap(ptr, SHM_SIZE);close(shm_fd);
}父进程通过信号量每1秒写一次数据写入完毕后执行post子进程一直阻塞等待获取到信号量后从共享内存读取数据测试结果如下 4、总结
本文阐述了进程间通信之共享内存(POSIX)的定义、应用场景、优缺点等列举了编程中使用的接口编写了测试用例测试相关功能。