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
[49201] Re:Re:Re:스레드 동기화 문제 - 힘듭니다.
공부맨 [] 1928 읽음    2007-05-08 16:41
메인 소스에서
: : :     m_pThread[0]->m_pEditFail = Edit2;
: : :     m_pThread[0]->m_pEditSucc = Edit7;
...

스레드에서
: : :         strRcv = Form1->m_RS232.SendString(strSend, "\r\n", "");
: : :         if (strRcv.AnsiCompare("\r\n") != 0)
: : :         {
: : :             int i = m_pEditFail->Text.ToInt ();
: : :             m_pEditFail->Text = IntToStr (++i);
: : :         }
: : :         else
: : :         {
: : :             int i = m_pEditSucc->Text.ToInt ();
: : :             m_pEditSucc->Text = IntToStr (++i);
: : :         }
하였으므로

서브스레드에서 메인스레드의 VCL에 접근하고 있습니다. (m_pEditFail, m_pEditSucc)
따라서 Synchronize를 사용하시면 될것입니다.

Synchronize 소스를 함 보시면 아시겠지만 내부적으로 새로운 기술은 아니고 Event + CriticalSection을 사용하고있습니다.(win32의 경우)
VCL이외의 데이터라도 동기화의 목적으로 사용하셔도 됩니다.


worldfip 님이 쓰신 글 :
: 메인폼에 있는 VCL은 공용으로 사용하는것은 없습니다.
: Synchronize 는 VCL컨트롤에만 적용되는 것으로 알고 있습니다.
: //   Important: Methods and properties of objects in VCL can only be
: //   used in a method called using Synchronize
:
:
:
: 권상득 님이 쓰신 글 :
: : 메인폼에 있는 놈들을 하위 스레드에서 사용하려면.. 반드시 Synchronize 를 사용하셔야 합니다.
: : 기본적으로 Synchronize 사용이 하나도 없는 걸로봐서 5개 스레드가 움직일때 문제가 없는것이 더 이상합니다.
: : 요행이 테스트에서 충돌이 없다고 해도 매우 위험한 처리 방법입니다.
: :
: : Synchronize(유저정의함수명); 이렇게 하면 됩니다.
: :
: : 유저정의함수는 반드시 리턴값도없고, 전달 인수도 사용할 수 없습니다. 따라서 전역변수를 사용하여 미리 값을주고
: : Synchronize 시에 유저정의 함수에서 전역변수를 이용하여 값을 주거나 받으시면 됩니다. 또한 메인폼에 있는 모든
: : 놈들을 마음껏 사용하셔도 됩니다.
: :
: : 메인폼에서 버튼을 클릭시에 하위스레드가 사용하는 시리얼 포트를 사용하려면
: : 1. 전역변수에 사용예약을 알리고
: : 2. 현재 사용중인 스레드가 하는일을 정상적으로 완료하여 끝나도록 합니다.
: : 3. 다음 스레드는 사용예약을 알리는 값을 먼저 읽어서 사용여부를 확인후 시리얼 포트를 사용하도록 합니다.
: : 4. 현재 사용중인 스레드가 일을 마치면 메인프로그램이 시리얼포트를 사용합니다.
: : 5. 메인프로그램이 사용을 마치면 사용예약 값을 해제하여 다음 스레드가 시리얼 포트를 사용 하도록 합니다.
: : 이와같은 로직으로 처리 하시면 될듯 합니다..
: :
: : worldfip 님이 쓰신 글 :
: : : 일단 세마포어를 사용했습니다.
: : : 5개의 스레드가 같은 포트의 232 통신을 사용합니다.
: : : 통신방법은 질문을 던지고 응답을 받아야 합니다. 이게 1사이클입니다.
: : : 그래서 Semaphore = CreateSemaphore (NULL, 1, 1, NULL); 요렇게 했습니다.
: : : 몇개의 스레드가 동시 접근되면 주고-받는 사이클에서 miss가 발생되기 때문에 1개의 스레드만 접근하게끔...
: : :
: : : 또한 메인폼에서 버튼을 클릭했을때 같은 포트의 232 통신을 시도 합니다.
: : : 그런데 5개의 스레드가 운영될때는 서로간에 충돌없이 아주 잘 운영되었는데
: : : 메인폼에서 버튼을 눌러 통신을 시도하게 되면 프로그램이 Deadlock 되어 버립니다.
: : : 도저히 원인을 모르겠네요.
: : :
: : : Semaphore, CriticalSection, Event 모두 시도해 보았는데 똑같은 현상을 보이네요. 이거 해결책 없을까요?
: : :
: : :
: : :
: : :
: : : 메인 프로그램입니다.
: : : //---------------------------------------------------------------------------
: : :
: : : #include <vcl.h>
: : : #include <SyncObjs.hpp>
: : : #pragma hdrstop
: : :
: : : #include "Unit1.h"
: : : //---------------------------------------------------------------------------
: : : #pragma package(smart_init)
: : : #pragma resource "*.dfm"
: : : TForm1 *Form1;
: : : HANDLE Semaphore;
: : : //---------------------------------------------------------------------------
: : : __fastcall TForm1::TForm1(TComponent* Owner)
: : :     : TForm(Owner)
: : : {
: : :     m_RS232.Setup(1, 19200, 8, 1, "None");
: : :     m_RS232.Connect();
: : : }
: : : //---------------------------------------------------------------------------
: : :
: : : void __fastcall TForm1::FormShow(TObject *Sender)
: : : {
: : :     Semaphore = CreateSemaphore (NULL, 1, 1, NULL);
: : :
: : :     m_pThread[0] = new TTest(true);
: : :     m_pThread[0]->m_pEditFail = Edit2;
: : :     m_pThread[0]->m_pEditSucc = Edit7;
: : :     m_pThread[0]->m_iThreadNum = 1;
: : :     m_pThread[1] = new TTest(true);
: : :     m_pThread[1]->m_pEditFail = Edit3;
: : :     m_pThread[1]->m_pEditSucc = Edit8;
: : :     m_pThread[1]->m_iThreadNum = 2;
: : :     m_pThread[2] = new TTest(true);
: : :     m_pThread[2]->m_pEditFail = Edit4;
: : :     m_pThread[2]->m_pEditSucc = Edit9;
: : :     m_pThread[2]->m_iThreadNum = 3;
: : :     m_pThread[3] = new TTest(true);
: : :     m_pThread[3]->m_pEditFail = Edit5;
: : :     m_pThread[3]->m_pEditSucc = Edit10;
: : :     m_pThread[3]->m_iThreadNum = 4;
: : :     m_pThread[4] = new TTest(true);
: : :     m_pThread[4]->m_pEditFail = Edit6;
: : :     m_pThread[4]->m_pEditSucc = Edit11;
: : :     m_pThread[4]->m_iThreadNum = 5;
: : :
: : :     m_pThread[0]->Resume();
: : :     m_pThread[1]->Resume();
: : :     m_pThread[2]->Resume();
: : :     m_pThread[3]->Resume();
: : :     m_pThread[4]->Resume();
: : : }
: : : //---------------------------------------------------------------------------
: : :
: : :
: : : __fastcall TForm1::~TForm1()
: : : {
: : :     m_pThread[0]->Terminate();
: : :     WaitForSingleObject(m_pThread[0], INFINITE);
: : :     m_pThread[1]->Terminate();
: : :     WaitForSingleObject(m_pThread[1], INFINITE);
: : :     m_pThread[2]->Terminate();
: : :     WaitForSingleObject(m_pThread[2], INFINITE);
: : :     m_pThread[3]->Terminate();
: : :     WaitForSingleObject(m_pThread[3], INFINITE);
: : :     m_pThread[4]->Terminate();
: : :     WaitForSingleObject(m_pThread[4], INFINITE);
: : :     CloseHandle (Semaphore);
: : : }
: : :
: : : void __fastcall TForm1::Button1Click(TObject *Sender)
: : : {
: : :     AnsiString strRcv;
: : :
: : :     Button1->Enabled = false;
: : :
: : :     WaitForSingleObject(Semaphore, INFINITE);
: : :
: : :     strRcv = m_RS232.SendString("Main\r\n", "\r\n", "");
: : :     if (strRcv.AnsiCompare("\r\n") == 0)
: : :     {
: : :         int i = Edit1->Text.ToInt ();
: : :         Edit1->Text = IntToStr (++i);
: : :     }
: : :
: : :     ReleaseSemaphore (Semaphore, 1, NULL);
: : :
: : :     Button1->Enabled = true;
: : : }
: : : //---------------------------------------------------------------------------
: : :
: : :
: : :
: : :
: : :
: : :
: : : 스레드 프로그램입니다.
: : :
: : :
: : : //---------------------------------------------------------------------------
: : :
: : : #include <vcl.h>
: : : #include <SyncObjs.hpp>
: : : #pragma hdrstop
: : :
: : : #include "Unit2.h"
: : : #include "Unit1.h"
: : : #pragma package(smart_init)
: : : //---------------------------------------------------------------------------
: : :
: : : //   Important: Methods and properties of objects in VCL can only be
: : : //   used in a method called using Synchronize, for example:
: : : //
: : : //      Synchronize(UpdateCaption);
: : : //
: : : //   where UpdateCaption could look like:
: : : //
: : : //      void __fastcall TTest::UpdateCaption()
: : : //      {
: : : //        Form1->Caption = "Updated in a thread";
: : : //      }
: : : //---------------------------------------------------------------------------
: : : extern HANDLE Semaphore;
: : : __fastcall TTest::TTest(bool CreateSuspended)
: : :     : TThread(CreateSuspended)
: : : {
: : :     FreeOnTerminate = true;
: : : }
: : : //---------------------------------------------------------------------------
: : : void __fastcall TTest::Execute()
: : : {
: : :     AnsiString strSend, strRcv;
: : :     while (!Terminated)
: : :     {
: : :         Sleep (100);
: : :         strSend = "Thread="+IntToStr(m_iThreadNum)+"\r\n";
: : :
: : :         WaitForSingleObject(Semaphore, INFINITE);
: : :         strRcv = Form1->m_RS232.SendString(strSend, "\r\n", "");
: : :         if (strRcv.AnsiCompare("\r\n") != 0)
: : :         {
: : :             int i = m_pEditFail->Text.ToInt ();
: : :             m_pEditFail->Text = IntToStr (++i);
: : :         }
: : :         else
: : :         {
: : :             int i = m_pEditSucc->Text.ToInt ();
: : :             m_pEditSucc->Text = IntToStr (++i);
: : :         }
: : :         ReleaseSemaphore (Semaphore, 1, NULL);
: : :     }
: : : }
: : : //---------------------------------------------------------------------------

+ -

관련 글 리스트
49192 스레드 동기화 문제 - 힘듭니다. worldfip 1745 2007/05/08
49198     Re:스레드 동기화 문제 - 힘듭니다. 김시환 1597 2007/05/08
49200         Re:Re:스레드 동기화 문제 - 힘듭니다. worldfip 1538 2007/05/08
49193     Re:스레드 동기화 문제 - 힘듭니다. 권상득 1558 2007/05/08
49195         Re:Re:스레드 동기화 문제 - 힘듭니다. worldfip 1369 2007/05/08
49201             Re:Re:Re:스레드 동기화 문제 - 힘듭니다. 공부맨 1928 2007/05/08
49194         Re:Re:스레드 동기화 문제 - 힘듭니다. 전홍진 1693 2007/05/08
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.