|
각각의 Query가 하나의 ADOConnection에 연결되어 있나요?
그렇다면 아래의 코드만을 볼때에는 하나의 ADOConnection을 통해 2개의 Query가 동시에 실행될 여지가 충분히 있습니다. 왜냐하면 thread1의 CriticalSection1과 thread2의 CriticalSection2는 서로 개별적으로 동작하기 때문에 동기화가 이루어지지 않습니다.
아래에 질문하신 것처럼 하나의 CriticalSection을 2개의 thread에서 동기화를 시키셔야 될걸로 보입니다.
아니면 ADOConnection과 Query 2개를 각각 쌍으로 사용하시고 실제 DB쪽의 무결성은 SQL 서버에 맞기시는 것도 한 방법으로 보입니다만...
이상 허접답변이었습니다..
초보 님이 쓰신 글 :
: 크리티컬 섹션을 2개 선언하고
: CRITICAL_SECTION CriticalSection1;
: CRITICAL_SECTION CriticalSection2;
:
: FormCreate 함수에서
: InitializeCriticalSection(&CriticalSection1);
: InitializeCriticalSection(&CriticalSection2);
: 해 주었습니다.
:
: 장비로 부터 데이타를 수신받아서 DB(SQL 2000 Server)에 저장하는 프로그램입니다.
:
:
: 60여개 정도의 장비에서 30초정도 간격으로 각각 2~3개의 데이타(개당 250 byte정도)가 계속 수신됩니다.
: 문제는 수신될때 많은 데이타가 한꺼번에 쏟아져서 들어오기 때문에 쓰레드를 사용하지 않으면
: 계속 응답없음 상태가 되어 버립니다.
:
: 책을 보고 여기에서 자료도 찾아보고 아래와 같이 했는데
: Error가 납니다.
:
: 탐색기에서 실행하면
: "Access violation at address-- 'VCL50.BPL', Read of address-- " 이렇게 나오고
:
: 디버그 모드에서 실행하면
: "Project TEST.EXE raised exception class EOleException -- '다른 명령 결과 때문에 연결을 사용중
: 입니다.', ---" 이렇게 나오면서 예외처리부분으로 빠져 버립니다.
:
:
: EnterCriticalSection
: 이안에서 저장하는 함수를 호출하니까 저장하는 동안에는 다른 스레드는 사용이 안되야 하는거 아닌가요?
: LeaveCriticalSection
:
: 2개의 쓰레드중에 1개만 사용하면 에러없이 실행이 됩니다.
: 스레드를 잘못 사용한건지 아래 저장하는 루틴이 잘못된건지 모르겠네요.
: 이부분 가지고 일주일 넘게 고생하고 있네요.
:
: 아시는분 부탁드립니다.
:
:
: // 데이타 수신받는 클래스에서 아래처럼 데이타 수신될때마다 스레드를 호출합니다.
: Thread1[소켓번호] = new TThread1(소켓번호);
: Thread1[소켓번호]->Resume();
:
: Thread2[소켓번호] = new TThread2(소켓번호);
: Thread2[소켓번호]->Resume();
:
:
:
:
: // 1번째 쓰레드
: __fastcall TThread1::TThread1(int nNum): TThread(true)
: {
: FreeOnTerminate = true;
: }
: //---------------------------------------------------------------------------
:
: void __fastcall TThread1::Execute()
: {
: while(!Terminated)
: {
: EnterCriticalSection(&CriticalSection1);
: Sleep(10);
: SAVE_1();
: LeaveCriticalSection(&CriticalSection1);
:
: Terminate();
: break;
: }
: }
: //---------------------------------------------------------------------------
:
:
: // 2번째 쓰레드
: __fastcall TThread2::TThread2(int nNum): TThread(true)
: {
: FreeOnTerminate = true;
: }
: //---------------------------------------------------------------------------
:
: void __fastcall TThread2::Execute()
: {
: while(!Terminated)
: {
: EnterCriticalSection(&CriticalSection2);
: Sleep(10);
: SAVE_2();
: LeaveCriticalSection(&CriticalSection2);
:
: Terminate();
: break;
: }
: }
: //---------------------------------------------------------------------------
:
: // 수신데이타 저장
:
: void CPoll::SAVE_1(int N1, int N2, int N3)
: {
: try
: {
: adoqry1->Close();
: adoqry1->SQL->Clear();
:
: adoqry1->SQL->Text = "프로시져명1 :N1, :N2, :N3";
: adoqry1->Parameters->Items[0]->Value = N1;
: adoqry1->Parameters->Items[1]->Value = N2;
: adoqry1->Parameters->Items[2]->Value = N3;
:
: adoqry1->ExecSQL();
: }
: catch(const EOleException &E)
: {
: ado_Connect->Connected = false;
: }
: }
: //---------------------------------------------------------------------------
:
: void CPoll::SAVE_2(int N1, int N2, int N3)
: {
: try
: {
: adoqry2->Close();
: adoqry2->SQL->Clear();
:
: adoqry2->SQL->Text = "프로시져명2 :N1, :N2, :N3";
: adoqry2->Parameters->Items[0]->Value = N1;
: adoqry2->Parameters->Items[1]->Value = N2;
: adoqry2->Parameters->Items[2]->Value = N3;
:
: adoqry2->ExecSQL();
: }
: catch(const EOleException &E)
: {
: ado_Connect->Connected = false;
: }
: }
: //---------------------------------------------------------------------------
|