|
일단 세마포어를 사용했습니다.
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);
}
}
//---------------------------------------------------------------------------
|