#include "shmfifo.h"
shmfifo_t *shmfifo_init(int key, int blksize, int blocks)
{
shmfifo_t *fifo = (shmfifo_t *)malloc(sizeof(shmfifo_t));
assert(fifo != NULL);
memset(fifo, 0, sizeof(shmfifo_t));
// 打开一块共享内存
int shmid = shmget(key, 0, 0);
// 如果打开失败, 则表示该共享内存尚未创建, 则创建之
if (shmid == -1)
{
/** 设置共享内存 **/
int size = blksize*blocks + sizeof(shmhead_t);
//创建共享内存
fifo->shmid = shmget(key, size, IPC_CREAT|0666);
if (fifo->shmid == -1)
err_exit("shmget error");
//创建共享内存成功, 则需要将其连接到进程的地址空间
//void *shmat(int shmid, const void *shmaddr, int shmflg);
fifo->p_shm = (shmhead_t *)shmat(fifo->shmid, NULL, 0);
if (fifo->p_shm == (void *) -1)
err_exit("shmat error");
//将共享内存的首部初始化为struct shmhead
fifo->p_shm->blksize = blksize;
fifo->p_shm->blocks = blocks;
fifo->p_shm->rd_index = 0;
fifo->p_shm->wr_index = 0;
fifo->p_payload = (char *)(fifo->p_shm+1);
/** 设置三个信号量 **/
fifo->sem_mutex = sem_create(key);
sem_setval(fifo->sem_mutex, 1);
fifo->sem_full = sem_create(key+1);
sem_setval(fifo->sem_full, blocks);
fifo->sem_empty = sem_create(key+2);
sem_setval(fifo->sem_empty, 0);
}
else
{
fifo->shmid = shmid;
//共享内存已经存在, 并且打开成功, 则需要将其连接到进程的地址空间
fifo->p_shm = (shmhead_t *)shmat(fifo->shmid, NULL, 0);
if (fifo->p_shm == (void *) -1)
err_exit("shmat error");
fifo->p_payload = (char *)(fifo->p_shm+1);
/** 设置三个信号量 **/
fifo->sem_mutex = sem_open(key);
fifo->sem_full = sem_open(key+1);
fifo->sem_empty = sem_open(key+2);
}
return fifo;
}
void shmfifo_put(shmfifo_t *fifo, const void *buf)
{
sem_P(fifo->sem_full);
sem_P(fifo->sem_mutex);
//从结构体中获取写入位置
char *index = fifo->p_payload +
(fifo->p_shm->wr_index * fifo->p_shm->blksize);
memcpy(index, buf, fifo->p_shm->blksize);
fifo->p_shm->wr_index = (fifo->p_shm->wr_index+1)%fifo->p_shm->blocks;
sem_V(fifo->sem_mutex);
sem_V(fifo->sem_empty);
}
void shmfifo_get(shmfifo_t *fifo, void *buf)
{
sem_P(fifo->sem_empty);
sem_P(fifo->sem_mutex);
//从结构体中获取读出位置
char *index = fifo->p_payload +
(fifo->p_shm->rd_index * fifo->p_shm->blksize);
memcpy(buf, index, fifo->p_shm->blksize);
fifo->p_shm->rd_index = (fifo->p_shm->rd_index+1)%fifo->p_shm->blocks;
sem_V(fifo->sem_mutex);
sem_V(fifo->sem_full);
}
void shmfifo_destroy(shmfifo_t *fifo)
{
sem_delete(fifo->sem_mutex);
sem_delete(fifo->sem_full);
sem_delete(fifo->sem_empty);
shmdt(fifo->p_shm);
if (shmctl(fifo->shmid, IPC_RMID, NULL) == -1)
err_exit("remove share memory error");
free(fifo);
}
绯青
- 粉丝: 3586
- 资源: 30
最新资源
- x64WinQSB安装程序v4.1
- 2023-04-06-项目笔记 - 第二百八十四阶段 - 4.4.2.282全局变量的作用域-282 -2025.10.12
- 数据集-目标检测系列- 降落伞 滑翔机 检测数据集 glider >> DataBall
- 数据集-目标检测系列- 战斗机 检测数据集 fighter-plane >> DataBall
- mybatis-plus代码生成自定义templates
- 数据集-目标检测系列- 手提包 检测 检测数据集 hand bag>> DataBall
- 自动化车间安全生产服务的标准制定与应用指南
- 520必备!这些Python表白代码祝你脱单成功,⼀、浪漫玫瑰花、⼆、浪漫玫瑰加爱⼼、三、⼼⼼相印、四、粉嫩爱⼼、五、丘⽐特⼀键
- 实现无线定位-chan算法,完整代码,适合参考学习使用
- 在 Excel 中实现相同和不同工作表中第7行及第7行之后的单元格内容相同时可以相互链接关联
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈