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
[69612] Re:Re:Re:Re:Re:Thread 조언 부탁드립니다..
김용덕 [srookie] 2212 읽음    2013-06-10 09:21
피니아 님이 쓰신 글 :
:  님이 쓰신 글 :
: : 피니아 님이 쓰신 글 :
: : : 김용덕 님이 쓰신 글 :
: : : : 피니아 님이 쓰신 글 :
: : : : : c++ 빌더 6에서 thread을 사용하여 실시간으로 차트에 데이터를
: : : : : 연속적으로 출력하는 부분을 만들고 있습니다.
: : : : :
: : : : : 헌데 thread는 정상적으로 도는것 같은대..
: : : : : 차트 출력이 되지안아 질문드립니다.
: : : : :
: : : : : 지금 구성은
: : : : : 연결 버튼을 클릭 하면 메인에서 데이터장치를 Initiallize를 합니다.
: : : : : 즉 장치와 연결을 하구요, 그 다음이 thread부분에서 장치로 부터
: : : : : 데이터를 얻어와 메인에 선언된 차트에 실시간으로 데이터를 뿌려주는 되는대
: : : : : 그 부분이 잘 안됩니다.
: : : : :
: : : : : 아직초보라서.. 자세한 설명부탁드립니다.
: : : : : thread 부분 헤더와 cpp 첨부합니다.!
: : : : :
: : : :
: : : : 안녕하세요.
: : : :
: : : : 소스를 보니 Display가 안될 수 밖에 없네요.
: : : :
: : : : Main Thread가 While Loop를 계속 수행하고 있기 때문에, Form의 Message Loop를 탈 수 있는 시간이 없네요.
: : : :
: : : : 그리고, 위의 첨부하신 소스를 보면 굳이 Thread를 쓸 필요가 있었는지 의문이 되네요.
: : : :
: : : : 차라리 타이머를 사용하는 것이 더 낫지 않을까 생각이 됩니다.
: : : :
: : : : 굳이 Thread를 사용하셔서 효율을 높이려면,
: : : :
: : : : Data를 얻어오는 부분과 Chart에 데이터를 넣는 부분을 구분하여 작업을 하시면 될 것 같네요.
: : : :
: : : : Data를 얻어오는 부분은 Thread에서 구현하고, Chart에 넣는 부분은 Main Thread에서 담당하도록요.
: : : :
: : : : 제 기억으로는 TChart가 Thread Safe하지 않은 걸로 알고 있네요.
: : : :
: : : : 도움이 되시길...
: : :
: : : 용덕님 답변 감사합니다. 말씀하신 부분 참고하여 thread 수정하였구요.
: : : thread 에서는 데이터만 취득해서 main으로 넘겨 차트에 뿌렸습니다.
: : : 한가지 더 궁금한 것이 있습니다.
: : : 차트에 값이 들어가 실시간으로 그래프가 그려지기는 합니다.
: : : 헌데 어떠한 이유인지는 모르겠지만 실시간이라기 보다 인터벌이 생깁니다.
: : : 측정장비에 손을 넣었다 빼면 한찬뒤에 차트에 그려지더라구요..;;
: : : 제가 보기에 어느정도 버퍼에 데이터를 쌓았다가 날리는것 같은대..
: : : 이런 부분은 어떻해 하지요?
: : : thread 소스 첨부 합니다.
: :
: : 안녕하세요.
: :
: : 소스를 확인해보니, 말씀하신것처럼 Data를 Thread에서 데이터만 취득하는 방식이 아니네요.
: :
: : 소스를 보면, Worker Thread에서 DataChart 라는 함수를 Synchronize를 이용해서 호출하셨는데요,
: :
: : 지금 작업하신 부분을 해석해 드리자면,
: :
: : Synchronize 함수는 Worker Thread가 Main Thread와의 동기를 맞추기 위해서,
: :
: : Synchronize 안에 있는 함수를 Main Thread에서 호출하라는 뜻이고,
: :
: : Worker Thread는 Synchonize 안에 있는 함수의 호출이 마쳐질때까지 Block되어 있게 됩니다.
: :
: : Worker Thread는 Main Thread가 DataChart를 호출하게 만들고, 끝날때까지 기다렸다가,
: :
: : 다시 Main Thread가 DataChart를 호출하게 만들고...
: :
: : 결국 Worker Thread는 하는 일이 없는거죠.
: :
: : 제가 이 소스에 대해서 정확하게는 모르지만, 대강 수정을 해본다면...
: :
: : void __fastcall ChartThread::Execute()
: : {
: :   Go2Data data = GO2_NULL;
: :   DataContext context;
: :   context.memory = NULL;
: :   double oriz = -294.91;
: :   int i =0;
: :   double x;
: :   double z;
: :
: :   while(!Terminated)
: :   {
: :   //while(!Terminated)
: :     while( i < NUM_PROFILES)
: :   {
: :     if (Go2System_ReceiveData(Form1->system, RECEIVE_TIMEOUT, &data) == GO2_OK)
: :     {
: :       for(j = 0; j < Go2Data_ItemCount(data); ++j)
: :       {
: :          OutputDebugString( IntToStr(j).c_str());
: :          //OutputDebugString( IntToStr(i).c_str());
: :          Go2Data dataItem = Go2Data_ItemAt(data, j);
: :          if (Go2Object_Type(dataItem) == GO2_TYPE_PROFILE_DATA)
: :          {
: :            unsigned int profilePointCount = Go2ProfileData_Width(dataItem);
: :        unsigned int profileSizeBytes = profilePointCount * sizeof(short int);
: :             //allocate memory
: :        if (context.memory == NULL)
: :        {
: :             context.memory = (short int*)malloc (NUM_PROFILES * profileSizeBytes);
: :            // context.memory = (short int*)malloc (2*profileSizeBytes);
: :        }
: :              context.profileWidth = Go2ProfileData_Width(dataItem);
: :          context.xResolution = Go2ProfileData_XResolution(dataItem);
: :          context.zResolution = Go2ProfileData_ZResolution(dataItem);
: :          context.xOffset = Go2ProfileData_XOffset(dataItem);
: :          context.zOffset = Go2ProfileData_ZOffset(dataItem);
: : //              memcpy(&context.memory[i * profilePointCount], Go2ProfileData_Ranges(dataItem), profileSizeBytes);
: :                 memcpy(&context.memory[profilePointCount], Go2ProfileData_Ranges(dataItem), profileSizeBytes);
: :           }
: :        }
: :       //여기서 Main Thread에 context Data를 넘겨줄 방법을 모색
: :      //참고로 여기서 Form1->CameraDataChart(&context); 를 호출하게되면 Worker Thread가 GDI를 건드리게 되서 에러가 발생할겁니다.
: :   }
: :     //Synchronize(DataChart);
: :         //---- Place thread code here ----
: : }
: :
: : 도움이 되시길...
:
:
: 말씀하신대로 코딩도 변경해보고 context를 다른 방법으로도 넘겨 보왔지만
: 역시나 인터벌이 생기네요.ㅠ
: 어떤 부분에서 버퍼에 쌓았다가 날리는 해결해보고 싶은대 정말 도통 모르겠습니다.
: main과 Thread를 같이 첨부합니다.ㅠ
: 무엇이 문제인지..; 지적 및 한말씀 부탁드립니다..!

흠...

첨부하신 테스트 소스를 봤습니다만,

일단 Worker Thread에서 Main Thread쪽으로 데이터를 넘기는 부분을 작업을 안하신것 같네요.

Main Source를 보면 Context를 받아서 화면에 뿌려주는 부분이 코딩되어있는것 같긴한데...

아래 김도완님의 답변처럼 Windows User Message를 통해서 Context를 넘기는 방법도 있을것이고,

아니면, Context를 담는 List를 만들어서, 수신한 Context를 추가한 다음에,

Main Thread에서 Timer 같은 것으로 수시로 찍어주는 방법도 있을 것 같습니다.

두가지 방법이 장단점이 있어서, 어느것이 더 낫다고는 말씀을 못드리겠네요.

그쪽 데이터의 상황을 모르기 때문에요...

그리고, 인터벌이 생기는 문제는 데이터 수신부의 시간이나, TChart에 데이터를 추가하는 부분이

정확하게 어느정도의 시간을 소요하는지 먼저 측정한 후에 다시 얘기하는것이 좋을 것 같습니다.

그럼 수고하십시오.

+ -

관련 글 리스트
69597 Thread 조언 부탁드립니다.. 피니아 1895 2013/06/05
69598     Re:Thread 조언 부탁드립니다.. 김용덕 2010 2013/06/05
69601         Re:Re:Thread 조언 부탁드립니다.. 피니아 1872 2013/06/05
69604             Re:Re:Re:Thread 조언 부탁드립니다.. 2022 2013/06/07
69607                 Re:Re:Re:Re:Thread 조언 부탁드립니다.. 피니아 1882 2013/06/07
69612                     Re:Re:Re:Re:Re:Thread 조언 부탁드립니다.. 김용덕 2212 2013/06/10
69608                     Re:Re:Re:Re:Re:Thread 조언 부탁드립니다.. 김도완 1931 2013/06/08
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.