1 Star 0 Fork 7

leonard/linux下共享内存和信号量集结合使用案例

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
shmfifo.c 2.41 KB
一键复制 编辑 原始数据 按行查看 历史
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <assert.h>
#include <string.h>
#include "shmfifo.h"
union semun { int value; };
static void p(int id)
{
struct sembuf sb[1];
sb[0].sem_num = 0;
sb[0].sem_op = -1;
sb[0].sem_flg = 0;
semop(id, sb, 1);
}
static void v(int id)
{
struct sembuf sb[1];
sb[0].sem_num = 0;
sb[0].sem_op = 1;
sb[0].sem_flg = 0;
semop(id, sb, 1);
}
shmfifo_t* shmfifo_init(int key, int blocks, int blksz)
{
shmfifo_t *p = (shmfifo_t*)malloc(sizeof(shmfifo_t));
assert(p);
int len = blocks * blksz + sizeof(head_t);
int shmid = shmget(key, len, 0);
if ( shmid == -1 ) { // 不存在,创建
shmid = shmget(key, len, IPC_CREAT|0644);
if ( shmid == -1 ) perror("shmget"),exit(1);
p->p_head = (head_t*)shmat(shmid, NULL, 0);
p->p_head->rd_idx = 0;
p->p_head->wr_idx = 0;
p->p_head->blocks = blocks;
p->p_head->blksz = blksz;
p->p_payload = (char*)(p->p_head+1);
p->shmid = shmid;
p->sem_empty = semget(key, 1, IPC_CREAT|0644);
p->sem_full = semget(key+1, 1, IPC_CREAT|0644);
p->sem_mutex = semget(key+2, 1, IPC_CREAT|0644);
union semun su;
su.value = 0;
semctl(p->sem_empty, 0, SETVAL, su);
su.value = blocks;
semctl(p->sem_full, 0, SETVAL, su);
su.value = 1;
semctl(p->sem_mutex, 0, SETVAL, su);
} else { // 存在
p->p_head = (head_t*)shmat(shmid, NULL, 0);
p->p_payload = (char*)(p->p_head+1);
p->shmid = shmid;
p->sem_empty = semget(key, 0, 0);
p->sem_full = semget(key+1, 0, 0);
p->sem_mutex = semget(key+2, 0, 0);
}
return p;
}
void shmfifo_put(shmfifo_t *fifo, const void *buf)
{
p(fifo->sem_full);
p(fifo->sem_mutex);
memcpy(fifo->p_payload+(fifo->p_head->wr_idx*fifo->p_head->blksz),
buf, fifo->p_head->blksz);
fifo->p_head->wr_idx =
(fifo->p_head->wr_idx + 1) % fifo->p_head->blocks;
v(fifo->sem_mutex);
v(fifo->sem_empty);
}
void shmfifo_get(shmfifo_t *fifo, void *buf)
{
p(fifo->sem_empty);
p(fifo->sem_mutex);
memcpy(buf, fifo->p_payload+(fifo->p_head->rd_idx*fifo->p_head->blksz), fifo->p_head->blksz);
fifo->p_head->rd_idx =
(fifo->p_head->rd_idx+1)%fifo->p_head->blocks;
v(fifo->sem_mutex);
v(fifo->sem_full);
}
void shmfifo_destroy(shmfifo_t *fifo)
{
shmdt(fifo->p_head);
shmctl(fifo->shmid, IPC_RMID, 0);
semctl(fifo->sem_full, 0, IPC_RMID);
semctl(fifo->sem_mutex, 0, IPC_RMID);
semctl(fifo->sem_empty, 0, IPC_RMID);
free(fifo);
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/leijiwu/shmfifo.git
git@gitee.com:leijiwu/shmfifo.git
leijiwu
shmfifo
linux下共享内存和信号量集结合使用案例
master

搜索帮助