同步问题使用 ftok + IPC.
可以参考 https://www.oschina.net/code/snippet_1160717_34522
点击(此处)折叠或打开
- #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" );
- }