一、基础概念
shmget
:用于创建或获取一个共享内存段。它需要一个键值(key)、共享内存的大小以及访问权限等参数。shmat
:将共享内存段附加到进程的地址空间。进程可以通过这个系统调用得到共享内存的地址,以便进行读写操作。shmdt
:将共享内存段从进程的地址空间中分离。shmctl
:用于对共享内存段进行控制操作,如删除共享内存段等。二、优势
三、类型
shmget
等系统调用来创建和管理共享内存段。shm_open
、mmap
等函数来操作POSIX共享内存。四、应用场景
五、可能出现的问题及解决方法
sem_wait
和sem_post
函数对共享内存的访问进行加锁和解锁操作。#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <stdio.h>
// 定义共享内存键值和大小
#define SHM_KEY 1234
#define SHM_SIZE 1024
// 定义信号量键值
#define SEM_KEY 5678
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
int main() {
int shmid, semid;
char *shmaddr;
struct sembuf sem_op;
// 创建共享内存段
shmid = shmget(SHM_KEY, SHM_SIZE, IPC_CREAT | 0666);
if (shmid < 0) {
perror("shmget");
return -1;
}
// 将共享内存附加到进程地址空间
shmaddr = (char *)shmat(shmid, NULL, 0);
if (shmaddr == (char *)( - 1)) {
perror("shmat");
return -1;
}
// 创建信号量集
semid = semget(SEM_KEY, 1, IPC_CREAT | 0666);
if (semid < 0) {
perror("semget");
return -1;
}
union semun arg;
arg.val = 1;
if (semctl(semid, 0, SETVAL, arg)!= 0) {
perror("semctl");
return -1;
}
// 进程1写入数据示例(假设是写操作)
sem_op.sem_num = 0;
sem_op.sem_op=-1;
sem_op.sem_flg = 0;
if (semop(semid, &sem_op, 1)!= 0) {
perror("semop write lock");
return -1;
}
sprintf(shmaddr, "Hello from process 1");
sem_op.sem_op = 1;
if (semop(semid, &sem_op, 1)!= 0) {
perror("semop write unlock");
return -1;
}
// 进程2读取数据示例(假设是读操作)
sem_op.sem_num = 0;
sem_op.sem_op=-1;
sem_op.sem_flg = 0;
if (semop(semid, &sem_op, 1)!= 0) {
perror("semop read lock");
return -1;
}
printf("Read from shared memory: %s
", shmaddr);
sem_op.sem_op = 1;
if (semop(semid, &sem_op, 1)!= 0) {
perror("semop read unlock");
return -1;
}
// 分离共享内存
if (shmdt(shmaddr)<0) {
perror("shmdt");
return -1;
}
return 0;
}
shmctl
函数并传入IPC_RMID
命令来删除共享内存段。同时,可以考虑设置合适的资源限制和监控机制,及时发现和处理异常情况。领取专属 10元无门槛券
手把手带您无忧上云