while문 때문에 죽겠습니다... ㅠ.ㅠ
글쓴이: yongwhe / 작성시간: 목, 2005/03/03 - 6:44오전
현재 특정 디렉토리에 파일을 읽어 파일안의 내용을 DB에 넣는 프로그램을 작성중에 있습니다.
DB(Oracle) 정상적으로 접속 되고 특정 디렉토리에 파일이 있는지 확인하고 파일이 존재하면 파일을 읽어 DB 입력작업을 하는 함수를 실행하는 함수에서 원인을 알 수 없는 문제가 생겨서 지금 죽겠습니다.
다음의 함수가 호출될때는 이미 정상적으로 DB에 접속되어 있는 상태이며 특정 디렉토리에 'end_'가 포함된 파일을 찾아서 'db_...'로 변경하고(파일명을) 파일을 열어서 db 입력함수(File_To_Db())를 호출하는 것인데 첫번째 while문을 주석처리하고 컴파일해서 돌리면 정상적으로 DB에 입력이 되는데 while을 주석처리하지 않고 돌리면 정상적으로 data를 입력했다고 message가 뿌려지는데 실제 db에는 update가 안되어 있습니다.
문제는 단발성으로 DB에 집어넣는게 아니라 그 특정 디렉토리를 주기적으로 확인하고 있다가 end_로 시작되는 file이 존재하면 그걸 db로 넣어야 되거든요...
한번 넣는것은 되는게 이걸 while문으로 돌리면 안되니 미치겠습니다.
특별하게 error 나는것도 없고...
고수님들 좀 봐주세요... ㅠ.ㅠ
void Insert_Data(Kind_No) int Kind_No; { FILE *fp; char buf[20], buf2[20], buf3[20]; char curr_filename[30]; char conv_filename[30]; int i, j, k, is_sucess; struct dirent *direntp; DIR *dirp; if((dirp = opendir("./ReceiveFile")) == NULL) { perror("Directory open error\n"); j = 0; } else { j = 1; } while(j) { memset(curr_filename, '\0', sizeof(curr_filename)); memset(conv_filename, '\0', sizeof(conv_filename)); k = 0; while((direntp = readdir(dirp)) != NULL) { memset(buf, '\0', sizeof(buf)); memset(buf2, '\0', sizeof(buf2)); memset(buf3, '\0', sizeof(buf3)); if((strstr(direntp->d_name, "end_")) == NULL) { continue; } else { strncpy(buf, direntp->d_name, 20); for(i = 0 ; i < 20 ; i++) { if(buf[i] == '\0') { break; } } sprintf(curr_filename, "./ReceiveFile/%s", strncpy(buf2, buf, i)); sprintf(conv_filename, "./ReceiveFile/db_%s", strncpy(buf3, buf2 + 4, i)); if((rename(curr_filename, conv_filename)) < 0 ) { perror("Data file move error\n"); continue; } else { k = 1; break; } } } if(k == 1) { if((fp = fopen(conv_filename, "r")) == NULL) { perror("Data file open error\n"); } else { is_sucess = File_To_Db(fp); if(is_sucess == 1) { perror("Db input error\n"); } else { printf("Db insert sucess\n"); } } fclose(fp); if((unlink(conv_filename)) < 0) { perror("Data file delete fail\n"); } } else { sleep(1); } rewinddir(dirp); } closedir(dirp); }
Forums:
while(j) 안에서 j의 값이 변하는 부분이 어디죠?
while(j) 안에서 j의 값이 변하는 부분이 어디죠?
세벌 https://sebuls.blogspot.kr/
while문 안에서는 j값이 변하질 않습니다. 즉 프로그램이 종료될때까지
while문 안에서는 j값이 변하질 않습니다. 즉 프로그램이 종료될때까지 특정 디렉토리를 계속 check 하면서 원하는 파일이 존재하면 계속 DB 작업을 수행하게 됩니다...
Re: while문 때문에 죽겠습니다... ㅠ.ㅠ
혹시 아래부분의 buf 가 20이여서 그런것이 아닐까요?
파일 길이가 20을 넘으면 아마도 fp을 덮어 써버릴것 같은데요.
buf를 20으로 하는 특별한 이유가 없으시다면 256등과 같이 늘려 잡아 주시는것 어떨지 .
음. 테스한 결과는 에러가 납니다만.. 이것이 문제인지 잘 모르겠네요.
고작 블로킹 하나, 고작 25점 중에 1점, 고작 부활동
"만약 그 순간이 온다면 그때가 네가 배구에 빠지는 순간이야"
[quote="yongwhe"][code:1]
엉뚱한 얘기인지는 모르겠지만 상식적으로 생각할 때 is_success가 1이면 성공을
뜻하는 거 아닌가요? 그러니까 if-else가 바뀌지 않았을까 하는 얘기...
buf size 문제도 아닙니다. check하는 파일명이 절대 20자 이
buf size 문제도 아닙니다. check하는 파일명이 절대 20자 이상이 되질 않습니다, 절대로...
그리고 is_sucess 변수 값도 문제가 되지 않습니다, 통상적으로 return value가 1이면 성공으로 저도 보통때는 그렇게
프로그래밍 했지만 File_To_Db() 함수의 return value가 1과 2 밖에 없습니다.
1이면 db update에 실패한거고 2면 성공한거죠...
원 프로그램에 함수가 3개 있습니다.
main, 문제의 함수 그리고 File_To_Db() 그리고 Pro*c쪽에 함수가 몇개 있는데 이거는 별 문제가 안되거든요...(DB 연결 및 연결재해 함수, db update 함수 <- File_To_Db() 함수에서 사용함)
main에서 db 연결하고 문제의 함수 호출합니다 -> 문제의 함수에서 특정 디렉토리에 원하는 파일(end_로 시작하는 파일) 있는지 확인
-> 있으면 File_To_Db()함수를 호출해서 해당 파일을 라인단위로 db에 입력합니다.
대충 logic이 이렇구요, 다른데서는 문제가 없습니다.
질문 올릴때도 설명드렸지만 test해볼 요량으로 while(j) 부분 주석처리하고 돌리면(특정 디렉토리에 end_로 시작하는 file 하나만 입력할때) 정상적으로 db update가 되는데
while문이 있으면 log상에 db update가 정상적으로 됐다고는 찍히는데 실제 data는 그대로 입니다.
이러니 미칠노릇이죠...
현상을 더이상 뭐라 설명드리기도 그렇고, 그렇다고 회사 보안상 풀소스를 올리기도 그렇고...
지금 귀신에 홀린 기분입니다...
커밋은 파일당 껀껀이 하나요?
커밋은 파일당 껀껀이 하나요?
울랄라~ 호기심 천국~!!
http://www.ezdoum.com
...
올려 놓으신 함수 자체에는 문제가 없어 보입니다.
다만 바깥 while문의 loop중단 조건이 없는 것으로 봐서 프로세스가 종료될 때까지 1초 주기로 말씀하신 작업을 하는 것으로 보이는데요... 프로세스가 종료되었을 때 closedir()이 반드시 호출된다는 보장도 없는 것 같고.
1초면 상당히 길다면 긴 시간인데 그동안에 close했다가 다시 open하는 것이 바람직하지 않을까 합니다.
이런 경우는 저렇게 무한루프와 sleep()을 사용하는 것 보다 timer를 이용하는 것이 보다 바람직할 것으로 생각됩니다. (저는 지금까지 이렇게 생각하고 있는데...그렇지 않나요? 진짜 고수님들...)
말씀하신 문제의 원인은 File_To_Db() 내에서 찾아 보시는 것이 어떨까 합니다. choissi님 말씀대로 커밋의 문제일 수도 있고,
또... File_To_Db()의 리턴 시점이 어떻게 되나요? 커밋까지 완전히 완료된 다음에 함수가 리턴되는 지 확인하실 필요가 있을 듯합니다. DB는 많이 다루어 보지 않았지만 DB호출도 어차피 프로세스간 통신인데 통신프로그램들 보면 request를 받으면 응답은 곧바로 보내 주고 실재 작업은 나중에 일어나는 경우를 많이 봤는데... 뭐 이런 것과 혹시 관련이 있지 않을까 하는 생각이 듭니다.
아는 것도 없으면서 혹시나 뒷걸음질 치다가 쥐잡을 요량으로 몇자 적어 본 것이니 너무 엉뚱한 소리라고 심하게 나무라지는 마시길...
답변 주신분들 감사합니다... ^^;드뎌 해결했습니다, 발상의 전환이
답변 주신분들 감사합니다... ^^;
드뎌 해결했습니다, 발상의 전환이라는게 무섭군요... 머리가 나쁘면 몸이 고생한다던데 제가 그짝이네요, 이 문제 때문에 3일 고생했는데...
역쉬 commit 문제였습니다...(허무 - 허탈)
원래 개발하고 사용했던 프로그램은 server program 이었는데 즉 접속 요청이 있으면 fork() -> db 접속 -> data update ->
db disconnect -> 프로그램 종료 이런 순이였습니다.
Pro*C의 disconnect 함수가 다음과 같이 생겼구요...
즉 이전에는 commit을 하면서 db접속을 해제했습니다, 근데 fork되는 자 Process의 개수가 많아지면서 server 및 db에 부하가 많이 걸리게 되서
socket 통신으로 전송되는 data를 file로 만들고 db 작업만 전문적으로 담당하는 program을 따로 만들어서 db 입력은 이것이 하도록
변경하는 작업을 하고 있는데 프로그램 자체를 종료할때를 제외하고 db_disconn() 함수를 호출할때가 없으니 당연히 db쪽에 data가
변경이 안되었던것 같습니다...^^(하도 만들어놓은지 오래된 소스라 제가그만 깜빡했습니다... ^^;)
commit 관련해서 Pro*C쪽에 조치를 했고, 정상적으로 도는거 확인했습니다...
일단 기본 logic은 문제가 없으니까 프로그램 다듬는 일만 남았네요, swellee님께서 언급하신데로 timer를 활용하는 방법도 좋을것 같고...
...
근데 heartbeat 관련 자료나, site 알고 계신분은 없나요? <= 물에서 건져주니까 보따리 내놓으라고 그러죠... ^^;
미천하고 아둔한 저의 물음에 신경써주시고 답변 해주신 모든 분들께 다시한번 감사드립니다...
저번에 계시판에서 heartbeat관련 정보를 본것 같습니다.검색
저번에 계시판에서 heartbeat관련 정보를 본것 같습니다.
검색 한 번 해보세요
♣♣♣♣♣♣ 폼나게 살자. 아님 말고~ ♣♣♣♣♣
댓글 달기