[질문] 이 소스에 머가 문제가 있어서.. 메시지큐가 작살이 날까요.. ㅠㅠ
글쓴이: oneclubs / 작성시간: 월, 2009/04/06 - 8:01오후
좀 이상하네요
쓰레드간에 통신을 할려고 하는데요
메인프로세서와 생성한 프로세스에서 간단히 메시지큐를 이용해서 데이터를 주고받고자 합니다..
쓰레드가 생성되고 나서 바로 메인프로세서는 msgrcv()상태로 들어가서 큐를 확인하고.. 메시지 있으면 꺼내서 출력하구요
생성된 쓰레드는..넘겨받은 값(5000)을 2배 3배 해서 10000 과 30000을 메시지큐에 넣습니다. 시간간격을 둬서
10000 넣고 3초 있다가 30000 넣습니다..
그럼 제가 생각한대로라면..
쓰레드에서 10000 넣으면 바로 메인에서 꺼내서 10000 출력하고 3초있다가 쓰레드가 또 30000 넣으면 메인에서 꺼내서 30000출력하구요..
이래야 하는데!!
생각대로 안되네요..
우선 무지무지 이상한게.. 그냥 while룹 탈출할려고 i값 2되면 나와라 했는데 msgrcv에서 값을 꺼내면서 i값이 이상하게 바뀌더라구요..
처음 실행할땐 생각대로 나오다가..루프탈출을 못해서 큐삭제를 못해서 그런가 2번째 부터는
아주 망가지네요..
아래 소스를 첨부할께요
#include < stdio.h> #include < stdlib.h> #include < pthread.h> #include < unistd.h> #include < sys/ipc.h> #include < sys/msg.h> #include < sys/types.h> #define QKEY (key_t)0102 #define QPERM 0660 struct buffers{ long mtype; char buf[100]; int value; }; void *threadFunction(void *data) { int cons = *((int*)data); struct buffers test2; int queue_id; cons *=2; printf("[c] I send this value %d",cons); if ( (queue_id = msgget(QKEY, IPC_CREAT | QPERM)) <0 ) { perror("msgget() error"); exit(1); } test2.value = cons; if ( msgsnd(queue_id, &test2, sizeof(struct buffers) - sizeof(long), 0) < 0 ) { perror("msgsnd() error"); exit(1); } printf("[c] I die!\n"); } int main() { pthread_t thread; int value= 5000; int thr_id; int queue_id; int status; struct buffers test; if ( (queue_id = msgget(QKEY, IPC_CREAT | QPERM)) <0 ) { perror("msgget() error"); exit(1); } thr_id = pthread_create(&thread , NULL, threadFunction, (void *)&value ); if ( thr_id <0 ) { perror("pthread_create error : "); exit(1); } while(1) { if ( msgrcv(queue_id, &test, sizeof(struct buffers) - sizeof(long), 0, 0) < 0) { perror("msgrcv error : "); exit(1); } else { printf("somebody send %d\n",test.value); break; } } printf("waiting to die child\n"); pthread_join(thread, (void **)&status); printf("return thread 0 is %d\n", status); return 0; }
Forums:
쓰레드간 정보 교환용 메모리를 따로 두십시오.
제목 그대로 메모리의 종류가 어떤 것이 있는지, 그 메모리가 어디서 왔다가 어디로 사라지는지를 생각해보셔야 합니다.
main 에서 쓰레드 생성할 때 전달하는 정보 교환용으로 쓰려고 하는 주소가 만들어진 쓰레드에서 어떻게 사용되고 있습니까? 또, 메시지를 전달할 때 로컬 변수의 주소를 넣었는데 그 쓰레드가 없어지게 되면 그 주소가 가리키는 메모리는 의미 있는 것일까요?
대부분의 플랫폼에서 위 프로그램은 루프 한번 돌고 그 다음 루프에서 (*3 해서 메시지 보내고 나서) 만들어진 쓰레는 종료될 것이고 main 쓰레드에서 메시지를 받았는데, '어?' 하는 것일 겁니다.
그 '어?' 하는 순간의 메모리 상황을 잘 생각해보시고 해결 방법을 생각해보시기 바랍니다.
p.s. 자기글에 + 를 줄 수 있다는 것에 놀라고 있습니다...
그러니까..
계속 테스트를 해보니 메모리박살 현상은 없는듯한데
msgsnd()에서 invalid argument가 나오네요.. 이런 잠못자게 생겼군요 ㅠ
그전에 소스가 좀 이상해서 일단 단순하게 고쳤는데 에러는 똑같네요.. invalid argument..
문제는 해결했으나 이유는 모르는 사태..
자문자답..
위의 소스에서
main에서 rcv를 받고 thread에서 send를 하는데..
이를 거꾸로 바꿔서 main에서 send하고 thread에서 recv하면 send실패가 발생하지 않습니다.
이유는 모르겠습니다.. 더 미치겟군요 ㅠㅠ
추가로 생성한
추가로 생성한 쓰레드가 3초후에 메시지를 보내고 어떻게 되는지 생각해보시기 바랍니다.
쓰레드에서 쓰고 있는 구조체를 담고 있는 로컬 변수가 쓰레드가 종료되면, 유효할 것이라고 생각하시면 안됩니다.
'어?' 하는 순간이 오시기를 바라면서...
전, 죽지 않았다는
전, 죽지 않았다는 것에서 '어?'가 나오네요. 변수가 무효화 되었는데도.
msgq 써본적은 없지만
msgq 써본적은 없지만 manpage를 보니 주어진 argument가 가리키는 영역을 '복사'해서 msgq에 넣는다고 되어있네요.
힌트: sizeof(struct
힌트:
참고:
질문과는 상관없지만, IPC의 일종인 message queue를 thread간 통신에 쓴 이유가 있나요? 차라리 mutex를 걸고, queue를 직접 구현하는 게 더 나을 듯.
--
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://www.cinsk.org/cfaqs/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
아....
쓰레드와 큐를 이용한 거에 답은 못찾았습니다. 아무리 바꾸고 바꾸고 쌩 쑈를 했는데도..
어떨때는 msgsnd에서 invalid argument..ㅠㅠ 어떨때는 전송이 되고..
전송하는 쓰레드에 시간차를 두는둥.. 별짓을 다해봤지만 비슷한 사태가..
결국 cinsk님 말대로 mutex 로 큐만들고 있습니다.. 큐만들기 귀찮아서 메시지큐를 쓰자! 라고 했는데.. 더 시간만 날려먹고
리눅스 포기직전 상태 ㅋ 엉엉
음..
thread 함수 보니, mtype 에서 값을 정의하지 않으셨요..
mtype 이 nonpositive 일 경우에는, EINVAL 이 리턴됩니다.
msgsnd 함수의 man page 에서 ERRORS 를 참고하세요.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
댓글 달기