代码拉取完成,页面将自动刷新
同步操作将从 钟岩/linux下共享内存和信号量集结合使用案例 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
#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);
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。