通过信号量和共享内存实现h264码流在不同进程间传输
2017-03-07 19:02
447 查看
读写这两个进程需要共享的内存,在头文件中定义,
其中single_frame,存放单个视频帧,mul
4000
_frame存放多帧的队列,其中count用来记录帧的数量,readIdx和writeIdx用来记录读帧和写帧的游标,通过结构体实现内存共享,便于操作。
写入进程的共享内存初始化代码
其中共享内存的keyid为1234,用于不同进程间设置同一的keyid,共享内存的大小为sizeof(mul_frame),可以自定义,这在linux上优于命名管道(fifo),因为命名管道
只能缓冲65536bytes,但是命名管道自带同步机制,而共享内存没有,所以需要定义信
号量sem_t* sem,其中mysem为信号量的keyid,同样用于不同进程间共享。
下面是写入进程的共享内存析构代码
读取共享内存的初始化的代码
读取共享内存的代码与写共享内存的代码基本一致,其中sem_open不同,写入的代码中最后一个参数是1,而读取的代码中,最后一个参数是0。
读取共享内存的析构代码,暂略。
下面是写入共享内存的代码
下面是读取共享内存的代码
由于写入共享内存时,是通过网络接收,而读取共享内存是直接保存文件,网络接收的速度明显慢于保存文件,所以只需要在读取的时候加sem_wait,用来等待写入。
另外,通过%DZY_FRAME_COUNT,来实现环形缓冲区的效果。
#define DZY_FRAME_SIZE 300000 #define DZY_FRAME_COUNT 10 typedef struct single_frame { int length; char frame[DZY_FRAME_SIZE]; }single_frame; typedef struct mul_frame { int count; int readIdx; int writeIdx; single_frame frame[DZY_FRAME_COUNT]; }mul_frame;
其中single_frame,存放单个视频帧,mul
4000
_frame存放多帧的队列,其中count用来记录帧的数量,readIdx和writeIdx用来记录读帧和写帧的游标,通过结构体实现内存共享,便于操作。
写入进程的共享内存初始化代码
#include <sys/shm.h> #include <semaphore.h> int shmid; mul_frame *shared;//指向shm sem_t* sem; void *shm = NULL;//分配的共享内存的原始首地址 shmid = shmget((key_t)1234, sizeof(mul_frame), 0666|IPC_CREAT); shm = shmat(shmid, 0, 0); if(shm == (void*)-1) { fprintf(stderr, "shmat failed\n"); } printf("\nMemory attached at %X\n", (int)shm); shared = (mul_frame*)shm; shared->readIdx = 0; shared->writeIdx = 0; shared->count = 0; for(int i =0;i<DZY_FRAME_COUNT;i++) { shared->frame[i].length=0; } sem = sem_open("mysem", O_CREAT | O_RDWR , 0666, 1); if (sem == SEM_FAILED) { printf("errno open sem\n"); }
其中共享内存的keyid为1234,用于不同进程间设置同一的keyid,共享内存的大小为sizeof(mul_frame),可以自定义,这在linux上优于命名管道(fifo),因为命名管道
只能缓冲65536bytes,但是命名管道自带同步机制,而共享内存没有,所以需要定义信
号量sem_t* sem,其中mysem为信号量的keyid,同样用于不同进程间共享。
下面是写入进程的共享内存析构代码
//把共享内存从当前进程中分离 if(shmdt((void*)shared) == -1) { fprintf(stderr, "shmdt failed\n"); } //删除共享内存 if(shmctl(shmid, IPC_RMID, 0) == -1) { fprintf(stderr, "shmctl(IPC_RMID) failed\n"); } sem_destroy(sem);
读取共享内存的初始化的代码
int shmid; mul_frame *shared;//指向shm void *shm = NULL;//分配的共享内存的原始首地址 shmid = shmget((key_t)1234, sizeof(mul_frame), 0666|IPC_CREAT); if(shmid == -1) { fprintf(stderr, "shmget failed\n"); } //将共享内存连接到当前进程的地址空间 shm = shmat(shmid, 0, 0); if(shm == (void*)-1) { fprintf(stderr, "shmat failed\n"); } printf("\nMemory attached at %X\n", (int)shm); shared = (mul_frame*)shm; sem_t* sem; sem = sem_open("mysem", O_CREAT | O_RDWR , 0666, 0); if (sem == SEM_FAILED) { printf("errno open sem\n"); }
读取共享内存的代码与写共享内存的代码基本一致,其中sem_open不同,写入的代码中最后一个参数是1,而读取的代码中,最后一个参数是0。
读取共享内存的析构代码,暂略。
下面是写入共享内存的代码
//sem_wait(sem); //printf("shared->count:%d\n",shared->count); if(shared->count < DZY_FRAME_COUNT) { shared->frame[shared->readIdx].length = _rxH264Frame->GetFrameSize() - bytesUsed; memcpy(shared->frame[shared->readIdx].frame,_rxH264Frame->GetFramePtr() + bytesUsed,shared->frame[shared->readIdx].length); shared->readIdx = (shared->readIdx+1)%DZY_FRAME_COUNT; shared->count++; }else { printf("error, shared->count:%d\n",shared->count); } sem_post(sem);
下面是读取共享内存的代码
sem_wait(sem); //printf("shared->count:%d\n",shared->count); if(shared->count > 0) { *len = shared->frame[shared->writeIdx].length; memcpy(buf,shared->frame[shared->writeIdx].frame,*len); shared->writeIdx = (shared->writeIdx+1)%DZY_FRAME_COUNT; shared->count--; }else { printf("error, shared->count:%d\n",shared->count); } //sem_post(sem);
由于写入共享内存时,是通过网络接收,而读取共享内存是直接保存文件,网络接收的速度明显慢于保存文件,所以只需要在读取的时候加sem_wait,用来等待写入。
另外,通过%DZY_FRAME_COUNT,来实现环形缓冲区的效果。
相关文章推荐
- Linux下通过共享内存进行进程间通信,进程间同步使用信号量来实现
- 通过共享内存和信号量实现进程间的通信
- Linux下通过共享内存进行进程间通信,进程间同步使用信号量来实现
- 进程间共享内存(信号量实现同步)
- 两个不同的OS环境,通过中断和共享内存进行数据传输
- php-通过共享内存实现消息队列和进程通信
- 不同语言,系统通过共享内存方式实现信息交互
- 0907使用write函数向共享内存中写入数据,实现不同进程间的数据信息传递
- 进程间共享内存(信号量实现同步)
- 共享内存 —— 通过SharedPreferences实现进程间数据共享的问题详解
- 两个或多个进程之间通过Win32 API实现内存共享的方法(转)
- linux下通过共享内存在进程之间实现通信(system V)
- linux下的多进程通信(IPC)原理及实现方案(管道、队列、信号量、共享内存)
- 通过execve实现不同进程间文件描述符的共享
- windows下信号量和共享内存api, mark:共享内存实现进程间锁
- 通过共享内存,利用循环队列实现两个进程A,B之间的通信
- [转]进程间通过共享内存方式传输大数据
- 通过内存映射文件实现进程间数据共享
- 通过共享内存,实现两个进程A,B之间的通信
- 两个或多个进程之间通过Win32 API实现内存共享的方法(转)