세마포어 관련
글쓴이: 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:


제가 잘 모르고 글을 쓴것 같네요. 내용 지웁니다ㅠ
제가 잘 모르고 글을 쓴것 같네요.
내용 지웁니다ㅠ
댓글 달기