Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5000810
  • 博文数量: 1193
  • 博客积分: 12961
  • 博客等级: 上将
  • 技术积分: 14341
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-09 11:25
  • 认证徽章:
个人简介

偷得浮生半桶水(半日闲), 好记性不如抄下来(烂笔头). 信息爆炸的时代, 学习是一项持续的工作.

文章分类

全部博文(1193)

文章存档

2019年(169)

2018年(81)

2017年(80)

2016年(70)

2015年(52)

2014年(41)

2013年(51)

2012年(85)

2011年(45)

2010年(231)

2009年(287)

分类: 其他平台

2018-03-27 16:37:22

近来要把 ffmpeg中的视频帧同步到外边, 供另外一个程序调用.  pipe/udp都不太合适, 因为只想用最新的内容,以前的是可以抛弃的, 后面想想, 共享内存合适, 好久没用了,做个笔记记录下.

同步问题使用 ftok + IPC.
可以参考 https://www.oschina.net/code/snippet_1160717_34522


点击(此处)折叠或打开

  1. #include <sys/mman.h>
  2. #include <sys/types.h>
  3. #include <fcntl.h>
  4. #include <unistd.h>
  5. #include <stdint.h>
  6. #include <stdio.h>
  7. #include <errno.h>
  8. #include <string.h>

  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11. #include <fcntl.h>
  12. #include <sys/mman.h>

  13. #include <sys/types.h>
  14. #include <sys/ipc.h>
  15. #include <sys/sem.h>
  16. static int semid = -1;

  17. union semun{
  18.     int val; /* Value for SETVAL */
  19.     struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
  20.     unsigned short *array; /* Array for GETALL, SETALL */
  21.     struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) */
  22. };

  23. typedef union semun semun_t;

  24. #define FFMPEG_VIDEO_SHM    "/tmp/a.txt"

  25. static void Mutex_Init(void)
  26. {
  27.     int key = ftok(FFMPEG_VIDEO_SHM, 0x66); //这个id = 0x66 必须使用相同的.
  28.     if (key < 0) {
  29.         fprintf(stderr, "ftok key error [%s].\n", strerror(errno));
  30.         exit(-1);
  31.     }
  32.     semid = semget(0x0900/*key*/, 1, IPC_CREAT | 0666 ); //创建一个信号量. 有则直接获取
  33.     if (semid == -1) {
  34.         fprintf(stderr, "semget error [%s].\n", strerror(errno));
  35.         semget(key, 0, 0);
  36.         exit(-1);
  37.     }
  38. #if 0
  39.     semun_t semun;
  40.     semun.val = 0;
  41.     int iret = semctl(semid, 0, SETVAL, semun);
  42.     if (-1 == iret) {
  43.         fprintf(stderr, "semctl SETVAL error [%s].\n", strerror(errno));
  44.         exit(-1);
  45.     }
  46. #endif    
  47. }

  48. static void Mutex_Remove(void)
  49. {
  50.     if (semid != -1) {
  51.         semctl(semid, 0, IPC_RMID, 0);
  52.     }
  53.     semid = -1;
  54. }

  55. typedef struct sembuf sembuf_t;
  56. static void Mutex_Lock(void)
  57. {
  58.     sembuf_t sembuf;
  59.     if (semid != -1) {
  60.         sembuf.sem_flg = SEM_UNDO;
  61.         sembuf.sem_num = 0;
  62.         sembuf.sem_op = -1; //-1 --> lock, 或者 1--> unlock
  63.         if ( -1 == semop(semid, &sembuf, 1)) {
  64.             fprintf(stderr, "semop error [%s].\n", strerror(errno));
  65.             exit(-1);
  66.         }
  67.     }
  68. }

  69. static void Mutex_Unlock(void)
  70. {
  71.     sembuf_t sembuf;
  72.     if (semid != -1) {
  73.         sembuf.sem_flg = SEM_UNDO;
  74.         sembuf.sem_num = 0;
  75.         sembuf.sem_op = 1; //-1 --> lock, 或者 1--> unlock
  76.         if ( -1 == semop(semid, &sembuf, 1)) {
  77.             fprintf(stderr, "semop error [%s].\n", strerror(errno));
  78.             exit(-1);
  79.         }
  80.     }
  81. }
  82. /*
  83.  * 0: OK, -1:can not lock.
  84.  * */
  85. static int Mutex_Trylock(void)
  86. {
  87.     sembuf_t sembuf;
  88.     if (semid != -1) {
  89.         sembuf.sem_flg = SEM_UNDO | IPC_NOWAIT;
  90.         sembuf.sem_num = 0;
  91.         sembuf.sem_op = -1; //-1 --> lock
  92.         return semop(semid, &sembuf, 1);
  93.     }
  94.     return -1;
  95. }

  96. /*
  97.  * 判断是否可用, 等待一段时间到确实可用.
  98.  * */
  99. static int Mutex_WaitZero(uint32_t usleep_cnt)
  100. {
  101.     sembuf_t sembuf;
  102.     struct timespec timeout = {0, 0/*nanoseconds*/};
  103.     if (usleep_cnt != 0) {
  104.         timeout.tv_sec = usleep_cnt / (1000);
  105.         timeout.tv_nsec = (usleep_cnt%1000) * 1000;
  106.     }
  107.     if (semid != -1) {
  108.         sembuf.sem_flg = SEM_UNDO;
  109.         sembuf.sem_num = 0;
  110.         sembuf.sem_op = 0; //判断是否可用.
  111.         if (usleep_cnt == 0) {
  112.             sembuf.sem_flg |= IPC_NOWAIT;
  113.             return semop(semid, &sembuf, 1); //不可用返回 -1, 可用为 0
  114.         }
  115.         else
  116.             return semtimedop(semid, &sembuf, 1, &timeout); //超时 返回 -1, errno=EAGAIN
  117.     }
  118.     return -1;
  119. }

  120. typedef struct{
  121.     int cnt;
  122.     char name[4];
  123.     int age;
  124. }people;

  125. main(int argc, char** argv) // map a normal file as shared mem:
  126. {
  127.     int fd,i;
  128.     people *p_map;
  129.     fd=open( "/tmp/Tmp",O_CREAT|O_RDWR,00777 );
  130.     p_map = (people*)mmap(NULL,sizeof(people),PROT_READ|PROT_WRITE, MAP_SHARED,fd,0);

  131.     Mutex_Init();

  132.     for(i = 0;i<10;i++)
  133.     {
  134.         while (1) {
  135.             if (0 == Mutex_Trylock()) {
  136.                 if (( *(p_map) ).cnt == 1) {
  137.                     ( *(p_map) ).cnt = 0;
  138.                     printf( "name: %s age %d;\n",(*(p_map)).name, (*(p_map)).age );
  139.                     Mutex_Unlock();
  140.                     break;
  141.                 }
  142.                 Mutex_Unlock();
  143.             }
  144.             usleep(10000);
  145.         }
  146.     }

  147.     Mutex_Remove();
  148.     munmap( p_map,sizeof(people)*10 );
  149. }

点击(此处)折叠或打开

  1. #include <sys/mman.h>
  2. #include <sys/types.h>
  3. #include <fcntl.h>
  4. #include <unistd.h>
  5. #include <stdint.h>
  6. #include <stdio.h>
  7. #include <errno.h>
  8. #include <string.h>

  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11. #include <fcntl.h>
  12. #include <sys/mman.h>

  13. #include <sys/types.h>
  14. #include <sys/ipc.h>
  15. #include <sys/sem.h>

  16. #define dbg()    printf("%d - %s.\n", __LINE__, __func__)

  17. static int semid = -1;

  18. union semun{
  19.     int val; /* Value for SETVAL */
  20.     struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
  21.     unsigned short *array; /* Array for GETALL, SETALL */
  22.     struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) */
  23. };

  24. typedef union semun semun_t;

  25. #define FFMPEG_VIDEO_SHM    "/tmp/a.txt"

  26. static void Mutex_Init(void)
  27. {
  28.     printf("如果要解决残留的sem, 可用命令行 ipcrm 搞定, 极端的用 sudo ipcrm --all=sem.\n");
  29.     dbg();
  30.     int key = ftok(FFMPEG_VIDEO_SHM, 0x66); //这个id = 0x66 必须使用相同的.
  31.     dbg();
  32.     if (key < 0) {
  33.         fprintf(stderr, "ftok key error [%s].\n", strerror(errno));
  34.         exit(-1);
  35.     }
  36.     dbg();
  37.     semid = semget(0x0900/*key*/, 1, IPC_CREAT | 0666 ); //创建一个信号量. 有则直接获取, 最后 9bit 为 权限 (for owner, group and others).
  38.     dbg();
  39.     if (semid == -1) {
  40.         dbg();
  41.         fprintf(stderr, "semget error [%s].\n", strerror(errno));
  42.         dbg();
  43.         semget(key, 0, 0);
  44.         exit(-1);
  45.     }
  46.     
  47. #if 1
  48.     dbg();
  49.     semun_t sem_buf;
  50.     sem_buf.val = 1;
  51.     int iret = semctl(semid, 0, SETVAL, sem_buf);
  52.     if (iret < 0) {
  53.         fprintf(stderr, "semctl SETVAL error [%s].\n", strerror(errno));
  54.         semctl(semid, 0, IPC_RMID, sem_buf);
  55.         exit(-1);
  56.     }
  57.     dbg();
  58. #endif    
  59. }

  60. static void Mutex_Remove(void)
  61. {
  62.     if (semid != -1) {
  63.         semctl(semid, 0, IPC_RMID, 0);
  64.     }
  65.     semid = -1;
  66. }

  67. typedef struct sembuf sembuf_t;
  68. static int sem_val = 0;
  69. static void Mutex_Lock(void) //P
  70. {
  71.     printf("Enter Mutex_Lock.\n");
  72.     sembuf_t sembuf;
  73.     if (semid != -1) {
  74.         sembuf.sem_flg = SEM_UNDO;
  75.         sembuf.sem_num = 0;
  76.         sembuf.sem_op = -1; //-1 --> lock, 或者 1--> unlock
  77.         if ( -1 == semop(semid, &sembuf, 1)) {
  78.             fprintf(stderr, "semop error [%s].\n", strerror(errno));
  79.             exit(-1);
  80.         }
  81.     }
  82. }

  83. static void Mutex_Unlock(void) //V
  84. {
  85.     printf("Enter Mutex_Unlock.\n");
  86.     sembuf_t sembuf;
  87.     sembuf.sem_num = 0;
  88.     
  89.     if (semid != -1) {
  90.         sem_val = semctl(semid,0,GETVAL,sembuf);
  91.         printf("before unlock, sem.val=%d.\n", sem_val);
  92.         
  93.         sembuf.sem_flg = SEM_UNDO;
  94.         sembuf.sem_num = 0;
  95.         sembuf.sem_op = 1; //-1 --> lock, 或者 1--> unlock
  96.         if ( -1 == semop(semid, &sembuf, 1)) {
  97.             fprintf(stderr, "semop error [%s].\n", strerror(errno));
  98.             exit(-1);
  99.         }
  100.         
  101.         sem_val = semctl(semid,0,GETVAL,sembuf);
  102.         printf("after unlock, sem.val=%d.\n", sem_val);
  103.     }
  104.     printf("Exit Mutex_Unlock.\n");
  105. }
  106. /*
  107.  * 0: OK, -1:can not lock.
  108.  * */
  109. static int Mutex_Trylock(void) //P
  110. {
  111.     int iret = -1;
  112.     printf("Enter Mutex_Trylock.\n");
  113.     sembuf_t sembuf;
  114.     sembuf.sem_num = 0;
  115.     
  116.     if (semid != -1) {
  117.         sem_val=semctl(semid,0,GETVAL,sembuf);
  118.         printf("before trylock, sem.val=%d.\n", sem_val);
  119.         
  120.         sembuf.sem_flg = SEM_UNDO | IPC_NOWAIT;
  121.         sembuf.sem_num = 0;
  122.         sembuf.sem_op = -1; //-1 --> lock
  123.         iret = semop(semid, &sembuf, 1);
  124.         
  125.         sem_val=semctl(semid,0,GETVAL,sembuf);
  126.         printf("after trylock, sem.val=%d.\n", sem_val);    
  127.     }
  128.     return iret;
  129. }

  130. /*
  131.  * 判断是否可用, 等待一段时间到确实可用.
  132.  * */
  133. static int Mutex_WaitZero(uint32_t usleep_cnt)
  134. {
  135.     sembuf_t sembuf;
  136.     struct timespec timeout = {0, 0/*nanoseconds*/};
  137.     if (usleep_cnt != 0) {
  138.         timeout.tv_sec = usleep_cnt / (1000);
  139.         timeout.tv_nsec = (usleep_cnt%1000) * 1000;
  140.     }
  141.     if (semid != -1) {
  142.         sembuf.sem_flg = SEM_UNDO;
  143.         sembuf.sem_num = 0;
  144.         sembuf.sem_op = 0; //判断是否可用.
  145.         if (usleep_cnt == 0) {
  146.             sembuf.sem_flg |= IPC_NOWAIT;
  147.             return semop(semid, &sembuf, 1); //不可用返回 -1, 可用为 0
  148.         }
  149.         else
  150.             return semtimedop(semid, &sembuf, 1, &timeout); //超时 返回 -1, errno=EAGAIN
  151.     }
  152.     return -1;
  153. }


  154. typedef struct{
  155.     int cnt;
  156.     char name[4];
  157.     int age;
  158. }people;

  159. main(int argc, char** argv) // map a normal file as shared mem:
  160. {
  161.     int fd,i;
  162.     people *p_map;
  163.     char temp;
  164.     
  165.     dbg();    
  166.     fd=open("/tmp/Tmp",O_CREAT|O_RDWR|O_TRUNC,00777);
  167.     lseek(fd,sizeof(people)-1,SEEK_SET);
  168.     write(fd,"",1);
  169.     dbg();
  170.     p_map = (people*) mmap( NULL,sizeof(people),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0 );
  171.     dbg();
  172.     close( fd );
  173.     dbg();
  174.     Mutex_Init();
  175.     dbg();
  176.     temp = 'a';
  177.     for(i=0; i<10; i++)
  178.     {
  179.         temp += 1;
  180.         while (1) {
  181.             if (0 == Mutex_Trylock()) {
  182.                 if (( *(p_map) ).cnt == 0) {
  183.                     ( *(p_map) ).cnt = 1;
  184.                     memcpy( ( *(p_map) ).name, &temp,2 );
  185.                     ( *(p_map) ).age = 20+i;
  186.                     Mutex_Unlock();
  187.                     break;
  188.                 }
  189.                 Mutex_Unlock();
  190.             }
  191.             usleep(100000);         
  192.         }
  193.     }
  194.     Mutex_Remove();
  195.     
  196.     munmap( p_map, sizeof(people)*10 );
  197.     printf( "umap ok \n" );
  198. }



阅读(1283) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册