C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[41742] [질문] 스레드를 이용한 다중 파일 복사에서 균등한 배분을 위하여...
냉큼이 [gladsky] 937 읽음    2005-09-01 16:01
안녕하세요. 언제나 눈팅만 하는 아직은 허접초짜입니다.

한개의 파일을 여러개의 USB에 복사시켜주는 프로그램을 만들고 있습니다.
그런데 테스트로 3개의 USB에 파일을 복사하는 테스트를 하다가
어느 한 USB에만 많은 시간이 할당되는 경우가 나타나서 질문하게 되었습니다.

참고적으로, 스레드 클래스 안에서 메인폼의 리스트뷰를 갱신하고
스레드 클래스 안에서 프로그래스바를 생성했다가 소멸하는 루틴이 있기는 합니다만
이것이 어느 한쪽으로만 몰리는 이유가 될까요?

아니면, 한개의 파일을 여러군데에서 오픈하여 사용하기 때문에
이런 현상이 나타나는 걸까요?

이 현상을 해결하고자 고민하다가 예전에 배웠던 자바에서
각 스레드들에게 시간(?)을 균등하게 분배해주는 무엇이 있었다는 생각이 어렴풋이 들었습니다.
혹시 C++에도 그런게 있지 않을까 해서요.

아래는 현재의 소스 일부입니다.

[main.cpp]
-----------------------------------------------------------------------------------
#include "ThreadUpGrade.h"

ThreadUpGrade   *UpThread[16];
unsigned char   DriveBuffer[26];

__fastcall TFormMain::TFormMain(TComponent* Owner)
    : TForm(Owner)
{
    int i;

    for (i = 0; i < 16; i++)
    {
        // 초기화
        UpThread[i] = NULL;
    }
}

void __fastcall TFormMain::BitBtnCopyClick(TObject *Sender)
{
    int i;

    for (i = 0; i < GetConnectCount(); i++)
    {
        UpThread[i] = new ThreadUpGrade(true);
        UpThread[i]->ThdID = i;
        UpThread[i]->ThdDrive = DriveBuffer[i]; // 연결된 USB의 드라이브 문자 배열
        UpThread[i]->ThdActive = true;
        UpThread[i]->ThdListView = ListViewStat; // 스레드에서 메인폼의 리스트뷰를 컨트롤하기 위하여
        UpThread[i]->Resume();
    }
}
-----------------------------------------------------------------------------------

[ThreadUpGrade.cpp]
-----------------------------------------------------------------------------------
void __fastcall ThreadUpGrade::Execute()
{
    //---- Place thread code here ----
    TestFileCopy();
}

void ThreadUpGrade::TestFileCopy(void)
{
    AnsiString source, target;

    source = "C:\\Test\\Test.DAT";
    target = (AnsiString)ThdDrive + ":\\Test.DAT";
    FileCopying(source, target, "Test.DAT");
}

bool ThreadUpGrade::FileCopying(AnsiString SourcePath, AnsiString TargetPath, AnsiString msg)
{
    HANDLE  hRead, hWrite;
    char    buf[BUF_SIZE];
    DWORD   dwret;
    int     file_size, result;
    TRect   rect;

    TListItem *tmpList;
    tmpList = ThdListView->Items->Item[ThdID];

    TProgressBar *pProgressBar = new TProgressBar(this);
    pProgressBar->Parent = ThdListView;

    // 소스파일을 얻어온다
    hRead = CreateFile(SourcePath.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL);
    if (hRead == INVALID_HANDLE_VALUE)
    {
//        ThdListView->Items->BeginUpdate();
        tmpList->SubItems->Strings[2] = "소스 파일을 찾을 수 없습니다.";
//        ThdListView->Items->EndUpdate();
        delete pProgressBar;
        CloseHandle(hWrite);
        return false;
    }

    // 대상파일을 얻어온다
    hWrite = CreateFile(TargetPath.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL);
    if (hWrite == INVALID_HANDLE_VALUE)
    {
//        ThdListView->Items->BeginUpdate();
        tmpList->SubItems->Strings[2] = "대상 파일을 만들 수 없습니다.";
//        ThdListView->Items->EndUpdate();
        delete pProgressBar;
        CloseHandle(hRead);
        CloseHandle(hWrite);
        return false;
    }

    // 메인폼의 리스트뷰 안에 프로그래스바를 표시하기 위함
    rect = ThdListView->Items->Item[ThdID]->DisplayRect(drBounds);
    pProgressBar->Top = rect.Top + BAR_PADDING;
    pProgressBar->Left = rect.Left + ThdListView->Columns->Items[1]->Width + ThdListView->Columns->Items[0]->Width;
    pProgressBar->Width = ThdListView->Columns->Items[2]->Width;
    pProgressBar->Height = rect.Height();

    pProgressBar->Min = 0;
    pProgressBar->Max = GetFileSize(hRead, NULL);
    pProgressBar->Position = 0;

    // 메세지를 작성한다
//    ThdListView->Items->BeginUpdate();
    tmpList->SubItems->Strings[2] = msg + " 파일을 복사중 입니다";
//    ThdListView->Items->EndUpdate();

    // 파일을 복사한다
    while (true)
    {
        memset(&buf, 0x00, BUF_SIZE);
        ReadFile(hRead, &buf, BUF_SIZE, &dwret, NULL);
        pProgressBar->Position += dwret;

        if (dwret == BUF_SIZE)
            WriteFile(hWrite, &buf, BUF_SIZE, &dwret, NULL);
        else if (dwret > 0)
            WriteFile(hWrite, &buf, dwret, &dwret, NULL);
        else
            break;
    }

    result = pProgressBar->Max - pProgressBar->Position;
    delete pProgressBar;
    CloseHandle(hRead);
    CloseHandle(hWrite);

    // 종료 메세지
    if ( !result )
    {
//        ThdListView->Items->BeginUpdate();
        tmpList->SubItems->Strings[1] = "복사 완료";
        tmpList->SubItems->Strings[2] = msg + " 파일을 복사하였습니다.";
//        ThdListView->Items->EndUpdate();
        return true;
    }
    else
    {
//        ThdListView->Items->BeginUpdate();
        tmpList->SubItems->Strings[1] = "복사 실패";
        tmpList->SubItems->Strings[2] = msg + " 파일 복사가 중단되었습니다.";
//        ThdListView->Items->EndUpdate();
        return false;
    }

    return false;
}
-----------------------------------------------------------------------------------

[ThreadUpGrade.h]
-----------------------------------------------------------------------------------
class ThreadUpGrade : public TThread
{
private:

protected:
    void __fastcall Execute();

public:
    char        ThdID;
    char        ThdDrive;
    bool        ThdActive;
    TListView   *ThdListView;

    void    TestFileCopy(void);
    bool    FileCopying(AnsiString SourcePath, AnsiString TargetPath, AnsiString msg);

    __fastcall ThreadUpGrade(bool CreateSuspended);
};
-----------------------------------------------------------------------------------

+ -

관련 글 리스트
41742 [질문] 스레드를 이용한 다중 파일 복사에서 균등한 배분을 위하여... 냉큼이 937 2005/09/01
41750     Re:[질문] 스레드를 이용한 다중 파일 복사에서 균등한 배분을 위하여... evergreen 1156 2005/09/02
41755         Re:Re:[질문] 지적 감사합니다. 냉큼이 925 2005/09/02
41748     Re:[질문] 스레드를 이용한 다중 파일 복사에서 균등한 배분을 위하여... WARSHIP 1106 2005/09/02
41754         Re:Re:[질문] 답변 감사드립니다. 냉큼이 872 2005/09/02
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.