세마포어 관련
글쓴이: asleea / 작성시간: 토, 2013/01/12 - 3:16오전
IPC 세마포어를 이용하여 2개의 세마포어 배열을 만들어 사용해 보려고 하는데
0번째 세마포어는 lock unlock 동작을 하는데 1번째 세마포어가 lock부분에서 블록되어 멈춰있네요
책이나 인터넷에는 다 1개만 이용한 예제밖에 없어 혹시 제가 함수를 잘못 사용해서 초기화를 했나하고
세마포어 초기화 및 사용 부분만 복사해서 올려봅니다.
혹시 잘못 된 부분있나요 .?
void setsembuf(struct sembuf* s, int num, int op, int flg) { s->sem_num = (short)num; s->sem_op = (short)op; s->sem_flg = (short)flg; return ; } static int semid; static struct sembuf semlock; static struct sembuf semunlock; static struct sembuf donelock; static struct sembuf doneunlock; semid = semget(key, 2, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR); setsembuf(&semlock, 0, -1, 0); setsembuf(&semunlock, 0, 1, 0); setsembuf(&donelock, 1, -1, 0); setsembuf(&doneunlock, 1, 1, 0); union semun { int val; struct semid_ds *buf; unsigned short *array; }arg; rg.val = 1; if(semctl(semid, 0, SETVAL, arg) == -1) return -1; if(semctl(semid, 1, SETVAL, arg) == -1) return -1; semop(semid, &donelock, 1); . . . semop(semid, &doneunlock, 1); semop(semid, &semlock, 1); . . . semop(semid, &semunlock, 1);
이 부분은 전체 코드 혹시나 해서..(공유메모리 에서 세마포어 사용)
main에 getdone()함수 donelock 부분에서 블록 되어있습니다.
#include<stdio.h> #include<sys/stat.h> #include<fcntl.h> #include<unistd.h> #include<stdlib.h> #include<time.h> #include<signal.h> #include<sys/sem.h> #include<sys/shm.h> #include<errno.h> typedef struct { int done; int count; int sum; sig_atomic_t setdone; }shared_arg; void setsembuf(struct sembuf* s, int num, int op, int flg) { s->sem_num = (short)num; s->sem_op = (short)op; s->sem_flg = (short)flg; return ; } static shared_arg *shared_memory; static int semid; static struct sembuf semlock; static struct sembuf semunlock; static struct sembuf donelock; static struct sembuf doneunlock; int initshared(int key) { int shid = shmget(key, sizeof(shared_arg), IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR); if((shid == -1) && (!EEXIST)) return -1; if(shid == -1) { shid = shmget(key, sizeof(shared_arg), S_IRUSR | S_IWUSR); if(shid == -1) return -1; shared_memory = (shared_arg*)shmat(shid, NULL, 0); if(shared_memory == (void*)-1) return -1; } else { shared_memory = (shared_arg*)shmat(shid, NULL, 0); if(shared_memory == (void*)-1) return -1; shared_memory->count = 0; shared_memory->sum = 0; shared_memory->done = 0; } fprintf(stderr, "shared memort OK\n"); setsembuf(&semlock, 0, -1, 0); setsembuf(&semunlock, 0, 1, 0); setsembuf(&donelock, 1, -1, 0); setsembuf(&doneunlock, 1, 1, 0); struct timespec sleeptime; sleeptime.tv_sec = 0; sleeptime.tv_nsec = 10000000; semid = semget(key, 2, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR); if((semid == -1) && (!EEXIST)) return -1; if(semid == -1) { semid = semget(key, 2, S_IRUSR | S_IWUSR); fprintf(stderr, "already sem exist and wait setdone\n"); while(!shared_memory->setdone) nanosleep(&sleeptime, NULL); fprintf(stderr, "setdone OK\n"); } else { fprintf(stderr, "new sem setting\n"); union semun { int val; struct semid_ds *buf; unsigned short *array; }arg; arg.val = 1; if(semctl(semid, 0, SETVAL, arg) == -1) return -1; if(semctl(semid, 1, SETVAL, arg) == -1) return -1; shared_memory->setdone = 1; } return 0; } int getdone(int *done) { if(semop(semid, &donelock, 1) == -1) return -1; fprintf(stderr, "doneloc\n"); *done = shared_memory->done; if(semop(semid, &doneunlock, 1) == -1) return -1; fprintf(stderr, "doneunlock\n"); return 0; } static int setdone(void) { if(semop(semid, &donelock, 1) == -1) return -1; shared_memory->done = 1; if(semop(semid, &doneunlock, 1) == -1) return -1; return 0; } int add(int x) { if(semop(semid, &semlock, 1) == -1) return -1; shared_memory->sum += x; shared_memory->count++; if(semop(semid, &semunlock, 1) == -1) return -1; return 0; } static int getsumandcount(int *sump, int *countp) { if(semop(semid, &semlock, 1) == -1) return -1; *sump = shared_memory->sum; *countp = shared_memory->count; if(semop(semid, &semunlock, 1) == -1) return -1; return 0; } int main(int argc, char *argv[]) { if(argc != 2) { fprintf(stderr, "Usage: %s <key>\n", argv[0]); return 1; } int key = atoi(argv[1]); int doneflag = 0; int rtn; int count = 0; int sum = 0; if(initshared(key) == -1) { fprintf(stderr, "initshared error\n"); return 1; } fprintf(stderr, "start adding x to sum\n"); while(!doneflag) { rtn = add(1); fprintf(stderr, "add, "); if(rtn == -1) { fprintf(stderr, "[%ld]:add error\n", (long)getpid()); return 1; } int rtn = getsumandcount(&sum, &count); fprintf(stderr, "getsumandcount, "); if(rtn == -1) { fprintf(stderr, "getsunadncount error\n"); return 1; } fprintf(stderr, "sum: %d, count: %d\n", sum, count); sleep(1); rtn = getdone(&doneflag); fprintf(stderr, "getdone....\n"); if(rtn == -1) { fprintf(stderr, "[%ld]:getdone error\n", (long)getpid()); return 1; } } fprintf(stderr, "doneflag on, process exit!!\n"); return 0; }
Forums:
제가 잘 모르고 글을 쓴것 같네요. 내용 지웁니다ㅠ
제가 잘 모르고 글을 쓴것 같네요.
내용 지웁니다ㅠ
댓글 달기