|
아더 님이 쓰신 글 :
: 안녕하세요. 이곳에서 많은 도움을 받고 있는 사람입니다. 매번 질문을 올릴때마다
:
: 친절한 답을 해주셔서 많은 분께 감사드립니다. 이번에도 도움을 부탁 드립니다.
:
: ------- 질문 ----------
: 하나의 프로그램에서 3가지 정도의 작업을 해야 하는데, 하나의 작업은
: 계속해서 파일 쓰기를 해야하는 작업입니다. 파일 쓰기를 하는 작업을
: 쓰레드를 하나 생성해서 하고 있는데, 파일쓰기를 할 경우 메시지 처리를
: 하지 못하는 것 같습니다. 아래서와 같이 스레드의 루프안에 일반 변수등의
: 계산에 관련된 명령만이 있을시는 스레드가 돌아가는 동안에 마우스도 잘움직이고
: 하는데, 파일쓰기등의 작업을 하면 마우스가 멈추거나 잘 움직이지 않습니다.
: 그래서 Application->ProcessMessages()를 사용해 보았는데, 별반차이가 없군요.
: 어떻게 해결할 수 있는 방법이 없을까요.
: 아참 그리고, 파일 작업 중 FileOpen, FileWrite 등의 API함수와 TFileStream의
: Builder 제공 함수와 fopen, fwrite 등의 ANSI 함수중 어떤 것이
: 제일 안정적이고 빠른지 알고 싶습니다.
: 제가 제 짧은 실력으로 테스트 해본 결과는 스피드 면에서 API, Builder 함수는
: 서로 비슷하고 ANSI 함수가 약간 느린것 같은데....
:
: 그럼 많은 가르침 부탁 드리겠습니다.
:
:
: -----------테스트 소스 일부------------------
: #include <vcl.h>
: #pragma hdrstop
:
: #include <stdio.h>
:
: #include "Unit2.h"
: #pragma package(smart_init)
:
: __fastcall FileThread::FileThread(bool CreateSuspended)
: : TThread(CreateSuspended)
: {
: FreeOnTerminate = true;
: }
: //---------------------------------------------------------------------------
: void __fastcall FileThread::Execute()
: {
: FILE* fp = fopen("test", "wb");
: int i;
: int buf[1024];
:
: do
: {
: 1-------> i++;
: 2-------> fwrite(buf, sizeof(int), 1024, fp);
: 3-------> Application->ProcessMessages();
: } while (!Terminated);
:
: 1)번 코드 같은 메모리 관련 명령만을 나열시 이벤트의 놓침이 없이
: 잘 돌아감(마우스의 움직임이 부드러움)(3번 코드 필요 없음)
: 2)번 같은 파일 쓰기 등의 명령이 루프안에 있으면 이벤트의
: 놓침이 있음. 3번코드를 추가해도 별반 차이가 없음(마우스가
: 움직이지 않거나 움직임이 부드럽지 못함)
:
:
: fclose(fp);
: }
: //---------------------------------------------------------------------------
:
안녕하세요. 수많은 테스트 결과 어느정도 자답(?)을 얻게 되었습니다.
우선 타이머(미디어 타이머 말고 그냥 타이머)를 사용해본 결과 메시지의
놓침이 없이(마우스등의 멈춤이 없이)잘 작동 되었습니다. 문제는
다른 메시지 처리가 바쁠 경우 타이머가 멈춰 버린다는 것입니다.
예로 마우스로 타이틀바를 계속 드래그 한다던가 할때 타이머가 멈추어 버립니다.
따라서 타이머를 사용할 경우 파일 저장의 시기가 중요하지 않은 경우
(하나의 파일에서 복사파일을 만들경우 같은)에는 상관없으나 저장시기가 중요한 경우에는
쓰지 않는 것이 좋을 것 같습니다.(예:일정 시간의 어떤 처리에의해 버퍼가 차서 그 것을 파일에
저장해야 할 경우 저장할 시기를 놓쳐버리면 다른 처리된 데이터가 버퍼를 께속 메꾸므로
데이터를 잃어버리게 됨)
다음은 스레드를 사용할 경우인데, 요점은 디스크나 CD의 경우 그 악세스 속도가 다른 것에
비해 엄청나게 느리다는 것입니다. 그리고 파일관련 내장 함수자체는 자체 타임쉐어링화
된것이 아니므로 (fwrite함수를 실행하기 위해 fwrite 함수에 진입하면 그 thread의
Time Priority가 끝났다고 하더라도 fwrite를 다 실행한후 복귀함)내장함수가 끝날때까지는
메시지의 처리도 이루어지지 못합니다.
따라서 파일관련 내장함수가 실행되는 시간(어느 하나의 함수 실행시간)을 최소화 하면
메시지의 놓침이나 먹통 현상을 막을 수 있습니다.
다음은 그 예입니다.
예, 사운드 카드 버퍼에 데이터가 차면 그 데이터를 파일로 저장,
샘플링 주파수 8000Hz 16비트 Resolution ==> 버퍼크기 8000(short int형)
버퍼에 데이터가 차면 Thread->Resume(), 버퍼데이터를 저장했으면 Thread->Suspend()
호출
.....
short int buf[8000];
do
{
fwrite((short int*)buf, sizeof(short int), 8000, fp);
} while(!Terminated);
====>
do
{
for (i = 0; i < 8000; i++)
{
fwrite((short int*)buf, sizeof(short int), 1, fp);
}
} while(!Terminated);
위에서와 같이 하면 이벤트의 놓침이 없이 잘 돌아 감니다.
(파일 저장 속도는 아래의 것이 약간 늦음) 그리고 for 문안에 Application->ProcessMessages();
를 사용하면 저장 속도가 많이 떨어지게 됨니다. 특별한 이유가 아니면
Application->ProcessMessages(); 를 사용할 필요가 없을 것 같습니다. 위의 코드에서는
한번에 저장하는 데이터를 1로 했는데, 하드 악세스가 빠르고 시스템이 빠를 경우
그 값을 약간 높여도 될 것 같습니다. 값을 점점 높여보면
저장 속도는 빨라지고, 마우스의 움직임은 점점 뻑뻑해짐을 알 수 있을 것입니다.
저의 컴퓨터의 경우는 10을 넘어가니까 , 뻑뻑해지기 시작하는 군요.
이리저리 테스트 해보고 여기저기 이거저것 물어보고해서 얻은 자답인데,
맞는지 모르겠군요. 혹시 제가 잘못알고 있는 것이 많은 조언 부탁드리겠습니다.
그럼 즐거운 하루 되세요..
|