近来要把 ffmpeg中的视频帧同步到外边, 供另外一个程序调用. pipe/udp都不太合适, 因为只想用最新的内容,以前的是可以抛弃的, 后面想想, 共享内存合适, 好久没用了,做个笔记记录下.
同步问题使用 ftok + IPC.
可以参考
-
#include <sys/mman.h>
-
#include <sys/types.h>
-
#include <fcntl.h>
-
#include <unistd.h>
-
#include <stdint.h>
-
#include <stdio.h>
-
#include <errno.h>
-
#include <string.h>
-
-
#include <sys/types.h>
-
#include <sys/stat.h>
-
#include <fcntl.h>
-
#include <sys/mman.h>
-
-
#include <sys/types.h>
-
#include <sys/ipc.h>
-
#include <sys/sem.h>
-
static int semid = -1;
-
-
union semun{
-
int val; /* Value for SETVAL */
-
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
-
unsigned short *array; /* Array for GETALL, SETALL */
-
struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) */
-
};
-
-
typedef union semun semun_t;
-
-
#define FFMPEG_VIDEO_SHM "/tmp/a.txt"
-
-
static void Mutex_Init(void)
-
{
-
int key = ftok(FFMPEG_VIDEO_SHM, 0x66); //这个id = 0x66 必须使用相同的.
-
if (key < 0) {
-
fprintf(stderr, "ftok key error [%s].\n", strerror(errno));
-
exit(-1);
-
}
-
semid = semget(0x0900/*key*/, 1, IPC_CREAT | 0666 ); //创建一个信号量. 有则直接获取
-
if (semid == -1) {
-
fprintf(stderr, "semget error [%s].\n", strerror(errno));
-
semget(key, 0, 0);
-
exit(-1);
-
}
-
#if 0
-
semun_t semun;
-
semun.val = 0;
-
int iret = semctl(semid, 0, SETVAL, semun);
-
if (-1 == iret) {
-
fprintf(stderr, "semctl SETVAL error [%s].\n", strerror(errno));
-
exit(-1);
-
}
-
#endif
-
}
-
-
static void Mutex_Remove(void)
-
{
-
if (semid != -1) {
-
semctl(semid, 0, IPC_RMID, 0);
-
}
-
semid = -1;
-
}
-
-
typedef struct sembuf sembuf_t;
-
static void Mutex_Lock(void)
-
{
-
sembuf_t sembuf;
-
if (semid != -1) {
-
sembuf.sem_flg = SEM_UNDO;
-
sembuf.sem_num = 0;
-
sembuf.sem_op = -1; //-1 --> lock, 或者 1--> unlock
-
if ( -1 == semop(semid, &sembuf, 1)) {
-
fprintf(stderr, "semop error [%s].\n", strerror(errno));
-
exit(-1);
-
}
-
}
-
}
-
-
static void Mutex_Unlock(void)
-
{
-
sembuf_t sembuf;
-
if (semid != -1) {
-
sembuf.sem_flg = SEM_UNDO;
-
sembuf.sem_num = 0;
-
sembuf.sem_op = 1; //-1 --> lock, 或者 1--> unlock
-
if ( -1 == semop(semid, &sembuf, 1)) {
-
fprintf(stderr, "semop error [%s].\n", strerror(errno));
-
exit(-1);
-
}
-
}
-
}
-
/*
-
* 0: OK, -1:can not lock.
-
* */
-
static int Mutex_Trylock(void)
-
{
-
sembuf_t sembuf;
-
if (semid != -1) {
-
sembuf.sem_flg = SEM_UNDO | IPC_NOWAIT;
-
sembuf.sem_num = 0;
-
sembuf.sem_op = -1; //-1 --> lock
-
return semop(semid, &sembuf, 1);
-
}
-
return -1;
-
}
-
-
/*
-
* 判断是否可用, 等待一段时间到确实可用.
-
* */
-
static int Mutex_WaitZero(uint32_t usleep_cnt)
-
{
-
sembuf_t sembuf;
-
struct timespec timeout = {0, 0/*nanoseconds*/};
-
if (usleep_cnt != 0) {
-
timeout.tv_sec = usleep_cnt / (1000);
-
timeout.tv_nsec = (usleep_cnt%1000) * 1000;
-
}
-
if (semid != -1) {
-
sembuf.sem_flg = SEM_UNDO;
-
sembuf.sem_num = 0;
-
sembuf.sem_op = 0; //判断是否可用.
-
if (usleep_cnt == 0) {
-
sembuf.sem_flg |= IPC_NOWAIT;
-
return semop(semid, &sembuf, 1); //不可用返回 -1, 可用为 0
-
}
-
else
-
return semtimedop(semid, &sembuf, 1, &timeout); //超时 返回 -1, errno=EAGAIN
-
}
-
return -1;
-
}
-
-
typedef struct{
-
int cnt;
-
char name[4];
-
int age;
-
}people;
-
-
main(int argc, char** argv) // map a normal file as shared mem:
-
{
-
int fd,i;
-
people *p_map;
-
fd=open( "/tmp/Tmp",O_CREAT|O_RDWR,00777 );
-
p_map = (people*)mmap(NULL,sizeof(people),PROT_READ|PROT_WRITE, MAP_SHARED,fd,0);
-
-
Mutex_Init();
-
-
for(i = 0;i<10;i++)
-
{
-
while (1) {
-
if (0 == Mutex_Trylock()) {
-
if (( *(p_map) ).cnt == 1) {
-
( *(p_map) ).cnt = 0;
-
printf( "name: %s age %d;\n",(*(p_map)).name, (*(p_map)).age );
-
Mutex_Unlock();
-
break;
-
}
-
Mutex_Unlock();
-
}
-
usleep(10000);
-
}
-
}
-
-
Mutex_Remove();
-
munmap( p_map,sizeof(people)*10 );
-
}
-
#include <sys/mman.h>
-
#include <sys/types.h>
-
#include <fcntl.h>
-
#include <unistd.h>
-
#include <stdint.h>
-
#include <stdio.h>
-
#include <errno.h>
-
#include <string.h>
-
-
#include <sys/types.h>
-
#include <sys/stat.h>
-
#include <fcntl.h>
-
#include <sys/mman.h>
-
-
#include <sys/types.h>
-
#include <sys/ipc.h>
-
#include <sys/sem.h>
-
-
#define dbg() printf("%d - %s.\n", __LINE__, __func__)
-
-
static int semid = -1;
-
-
union semun{
-
int val; /* Value for SETVAL */
-
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
-
unsigned short *array; /* Array for GETALL, SETALL */
-
struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) */
-
};
-
-
typedef union semun semun_t;
-
-
#define FFMPEG_VIDEO_SHM "/tmp/a.txt"
-
-
static void Mutex_Init(void)
-
{
-
printf("如果要解决残留的sem, 可用命令行 ipcrm 搞定, 极端的用 sudo ipcrm --all=sem.\n");
-
dbg();
-
int key = ftok(FFMPEG_VIDEO_SHM, 0x66); //这个id = 0x66 必须使用相同的.
-
dbg();
-
if (key < 0) {
-
fprintf(stderr, "ftok key error [%s].\n", strerror(errno));
-
exit(-1);
-
}
-
dbg();
-
semid = semget(0x0900/*key*/, 1, IPC_CREAT | 0666 ); //创建一个信号量. 有则直接获取, 最后 9bit 为 权限 (for owner, group and others).
-
dbg();
-
if (semid == -1) {
-
dbg();
-
fprintf(stderr, "semget error [%s].\n", strerror(errno));
-
dbg();
-
semget(key, 0, 0);
-
exit(-1);
-
}
-
-
#if 1
-
dbg();
-
semun_t sem_buf;
-
sem_buf.val = 1;
-
int iret = semctl(semid, 0, SETVAL, sem_buf);
-
if (iret < 0) {
-
fprintf(stderr, "semctl SETVAL error [%s].\n", strerror(errno));
-
semctl(semid, 0, IPC_RMID, sem_buf);
-
exit(-1);
-
}
-
dbg();
-
#endif
-
}
-
-
static void Mutex_Remove(void)
-
{
-
if (semid != -1) {
-
semctl(semid, 0, IPC_RMID, 0);
-
}
-
semid = -1;
-
}
-
-
typedef struct sembuf sembuf_t;
-
static int sem_val = 0;
-
static void Mutex_Lock(void) //P
-
{
-
printf("Enter Mutex_Lock.\n");
-
sembuf_t sembuf;
-
if (semid != -1) {
-
sembuf.sem_flg = SEM_UNDO;
-
sembuf.sem_num = 0;
-
sembuf.sem_op = -1; //-1 --> lock, 或者 1--> unlock
-
if ( -1 == semop(semid, &sembuf, 1)) {
-
fprintf(stderr, "semop error [%s].\n", strerror(errno));
-
exit(-1);
-
}
-
}
-
}
-
-
static void Mutex_Unlock(void) //V
-
{
-
printf("Enter Mutex_Unlock.\n");
-
sembuf_t sembuf;
-
sembuf.sem_num = 0;
-
-
if (semid != -1) {
-
sem_val = semctl(semid,0,GETVAL,sembuf);
-
printf("before unlock, sem.val=%d.\n", sem_val);
-
-
sembuf.sem_flg = SEM_UNDO;
-
sembuf.sem_num = 0;
-
sembuf.sem_op = 1; //-1 --> lock, 或者 1--> unlock
-
if ( -1 == semop(semid, &sembuf, 1)) {
-
fprintf(stderr, "semop error [%s].\n", strerror(errno));
-
exit(-1);
-
}
-
-
sem_val = semctl(semid,0,GETVAL,sembuf);
-
printf("after unlock, sem.val=%d.\n", sem_val);
-
}
-
printf("Exit Mutex_Unlock.\n");
-
}
-
/*
-
* 0: OK, -1:can not lock.
-
* */
-
static int Mutex_Trylock(void) //P
-
{
-
int iret = -1;
-
printf("Enter Mutex_Trylock.\n");
-
sembuf_t sembuf;
-
sembuf.sem_num = 0;
-
-
if (semid != -1) {
-
sem_val=semctl(semid,0,GETVAL,sembuf);
-
printf("before trylock, sem.val=%d.\n", sem_val);
-
-
sembuf.sem_flg = SEM_UNDO | IPC_NOWAIT;
-
sembuf.sem_num = 0;
-
sembuf.sem_op = -1; //-1 --> lock
-
iret = semop(semid, &sembuf, 1);
-
-
sem_val=semctl(semid,0,GETVAL,sembuf);
-
printf("after trylock, sem.val=%d.\n", sem_val);
-
}
-
return iret;
-
}
-
-
/*
-
* 判断是否可用, 等待一段时间到确实可用.
-
* */
-
static int Mutex_WaitZero(uint32_t usleep_cnt)
-
{
-
sembuf_t sembuf;
-
struct timespec timeout = {0, 0/*nanoseconds*/};
-
if (usleep_cnt != 0) {
-
timeout.tv_sec = usleep_cnt / (1000);
-
timeout.tv_nsec = (usleep_cnt%1000) * 1000;
-
}
-
if (semid != -1) {
-
sembuf.sem_flg = SEM_UNDO;
-
sembuf.sem_num = 0;
-
sembuf.sem_op = 0; //判断是否可用.
-
if (usleep_cnt == 0) {
-
sembuf.sem_flg |= IPC_NOWAIT;
-
return semop(semid, &sembuf, 1); //不可用返回 -1, 可用为 0
-
}
-
else
-
return semtimedop(semid, &sembuf, 1, &timeout); //超时 返回 -1, errno=EAGAIN
-
}
-
return -1;
-
}
-
-
-
typedef struct{
-
int cnt;
-
char name[4];
-
int age;
-
}people;
-
-
main(int argc, char** argv) // map a normal file as shared mem:
-
{
-
int fd,i;
-
people *p_map;
-
char temp;
-
-
dbg();
-
fd=open("/tmp/Tmp",O_CREAT|O_RDWR|O_TRUNC,00777);
-
lseek(fd,sizeof(people)-1,SEEK_SET);
-
write(fd,"",1);
-
dbg();
-
p_map = (people*) mmap( NULL,sizeof(people),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0 );
-
dbg();
-
close( fd );
-
dbg();
-
Mutex_Init();
-
dbg();
-
temp = 'a';
-
for(i=0; i<10; i++)
-
{
-
temp += 1;
-
while (1) {
-
if (0 == Mutex_Trylock()) {
-
if (( *(p_map) ).cnt == 0) {
-
( *(p_map) ).cnt = 1;
-
memcpy( ( *(p_map) ).name, &temp,2 );
-
( *(p_map) ).age = 20+i;
-
Mutex_Unlock();
-
break;
-
}
-
Mutex_Unlock();
-
}
-
usleep(100000);
-
}
-
}
-
Mutex_Remove();
-
-
munmap( p_map, sizeof(people)*10 );
-
printf( "umap ok \n" );
-
}
阅读(2788) | 评论(0) | 转发(0) |