델파이의 인디의 CheckForDisconnect, CheckForGracefulDisconnect..

서버 쪽의 연결 끊어짐을 알 수 있다고 해서 써봤는데...결과는 좀 실망이다...
CheckForGracefulDisconnect 가 그나마 CheckForDisconnect 보다는 낫다.
연결된 상태에서 서버가 돌아가고 있는 윈도우를 종료시켰을 때 CheckForDisconnect 는 예외가 발생하지 않았으나CheckForGracefulDisconnect 은 예외가 발생하였다.
게다가 CheckForGracefulDisconnect 는 Connected 프로퍼티의 값도 알아서 FALSE 로 바꿔준다.

하.지.만.
.
.
둘다 서버가 설치된 PC의 전원 코드를 확 뽑아서 끄거나 LAN 선을 살짝 뽑거나 해도 예외가 발생하지 않았다.
따라서 결국 그냥 연결이 정상인지 문제가 있는지를 주기적으로 확인하는 용도로 클라이언트를 하나 더 만들어서 서버에 연결시켜야야할 듯 하다.
Polling(주기적으로 검사하는 것을 Polling 라고 한다.)용 클라이언트와 실제 데이터를 주고받는 클라이언트 중의 어느 한 쪽이라도 접속에 문제가 생기면 다른 한쪽을 Disconnect 하여 연결 상태값을 동일하게 만들어야 할 것이다.
...뭔가 좀 복잡해지기 시작한다. 아...간단하게 자동화할 수는 없을까...라이브러리화 할 수는 없을까...

by Dark-Ryu | 2009/11/24 16:01 | 끄적끄적 | 트랙백 | 덧글(0)

ruby 삽질하다...1.86.27...

Ruby On Rails (일명 ROR) 에 대한 무성한 소문에 대한 호기심 때문에 책을 샀다.
그런데 책의 버전이 좀 낮았다.
뭐...까짓거 받아서 설치하지 하고 찾아봤다.
환경이 윈도우이고 설치법에 대해 잘 모르는지라 결국 Ruby 1.8.6 원클릭 인스톨러  를 설치했다.
뭐...잘 진행되는 듯 했다.
...MySQL 드라이버를 설치하기 전까지는 말이다.

C:\Program Files\Support Tools>gem install mysql
Successfully installed mysql-2.8.1-x86-mswin32
1 gem installed
Installing ri documentation for mysql-2.8.1-x86-mswin32...

No definition for next_result

No definition for field_name

No definition for field_table

No definition for field_def

No definition for field_type

No definition for field_length

No definition for field_max_length

No definition for field_flags

No definition for field_decimals

No definition for time_inspect

No definition for time_to_s

No definition for time_get_year

No definition for time_get_month

No definition for time_get_day

No definition for time_get_hour

No definition for time_get_minute

No definition for time_get_second

No definition for time_get_neg

No definition for time_get_second_part

No definition for time_set_year

No definition for time_set_month

No definition for time_set_day

No definition for time_set_hour

No definition for time_set_minute

No definition for time_set_second

No definition for time_set_neg

No definition for time_set_second_part

No definition for time_equal

No definition for error_errno

No definition for error_sqlstate
Installing RDoc documentation for mysql-2.8.1-x86-mswin32...

No definition for next_result

No definition for field_name

No definition for field_table

No definition for field_def

No definition for field_type

No definition for field_length

No definition for field_max_length

No definition for field_flags

No definition for field_decimals

No definition for time_inspect

No definition for time_to_s

No definition for time_get_year

No definition for time_get_month

No definition for time_get_day

No definition for time_get_hour

No definition for time_get_minute

No definition for time_get_second

No definition for time_get_neg

No definition for time_get_second_part

No definition for time_set_year

No definition for time_set_month

No definition for time_set_day

No definition for time_set_hour

No definition for time_set_minute

No definition for time_set_second

No definition for time_set_neg

No definition for time_set_second_part

No definition for time_equal

No definition for error_errno

No definition for error_sqlstate

C:\Program Files\Support Tools>

허허...한참 지우고 새로 깔고...갖가지 삽질을 하다 ruby186-25.exe 를 설치했다.
그러니 책에 나온대로 되었다.
받았던 것이 release candidate2 ... candidate 는 '후보자'라는 뜻이라는 것이 생각났고 No definition for 라는 것이 gem 이 드라이버와 관계된 모듈들을 다운 받으려고 시도했지만 실패했다는 의미인 듯 했다.
...결론은 후보자니까 MySQL 드라이버를 다운 받을 수 있는 준비가 안 되어 있다는 것으로 짐작된다는 것이다.
......물론 짐작한 것이 틀렸을 수도 있다.
여튼 ruby186-25 을 설치하고 쓰고 있다.

또 다른 문제가 나타나고 또 다른 삽질을 할 수 있지만 뭐...Ruby 는 재밌을 것 같다는 생각이 든다.


2009.11.24. 위의 이상한 메시지에도 불구하고 그냥저냥 동작하는 듯 하다...MySQL 을 사용하는 코드를 안 짜서 아직은 모르겠지만 그럴 듯 하다...;;

by Dark-Ryu | 2009/11/11 16:59 | 끄적끄적 | 트랙백 | 덧글(0)

델파이로 병렬포트 이용하기...

어제 병렬포트에서 RF 센서의 입력을 받아야 하는 상황이 있었습니다.
그런데...포트를 읽을 때마다 255 (=0xFF, 0b11111111) 이더군요.
입력이 없는 Floating 상태에서는 내부적으로 풀업되어 있으니 255 가 나오는 것은 맞는데
2번핀을 25번핀에 연결했을 때는 254가 나와야 하는데 255 라서 곤란했습니다.

(병렬포트의 2번~9번 핀은 데이터 D0~D7 입니다., 18~25번 핀은 Ground 입니다.
2번핀을 25번핀에 연결하면
D7 D6 D5 D4 | D3 D2 D1 D0
  1   1   1   1     1   1   1   0    = 0b11111110 = 0xFE = 254
가 되어야 합니다.)

어제는 급해서...STROBE 핀을 이용해서 입력을 받았습니다. 날새고 한참 자고 일어나서 지금 책을 찾아보고 이유를 알았습니다.

병렬포트는 Control 포트를 이용하여 병렬 포트를 제어합니다. Data 포트의 입출력 방향도 바꿉니다.
C5 = 0 이면 Output 이고 C5 = 1 이면 Input 입니다.
따라서 Data 포트로 입력을 받으려면 C5에 1을 출력하고 Data 포트를 읽어야 했던 것입니다.

다음은 델파이 7에서 io.dll 을 이용해서 병렬포트를 통해 값을 출력하거나 입력받는 프로그램입니다.
io.dll 말고 다른 라이브러리를 사용할 경우 dll 참조부분과 함수 이름만 수정하시면 됩니다.


unit uMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

const DATA1 = $378;
const DATA2 = $278;
const STATUS1 = $379;
const STATUS2 = $279;
const CONTROL1 = $37A;
const CONTROL2 = $27A;

type
  TForm1 = class(TForm)
    btRead: TButton;
    Memo1: TMemo;
    edWriteValue: TEdit;
    btWrite: TButton;
    cbxSelPort: TComboBox;
    procedure btReadClick(Sender: TObject);
    procedure btWriteClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

procedure PortOut(Port : Word; Data : Byte); stdcall; external 'io.dll';
function PortIn(Port:Word):Byte; stdcall; external 'io.dll';

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btReadClick(Sender: TObject);
var
  iTmpDataPort: Integer;
  iTmpControlPort: Integer;
  byInValue: Byte;
begin
  if cbxSelPort.Text = '0x378' then begin
    iTmpDataPort := DATA1;
    iTmpControlPort := CONTROL1;
  end;
  if cbxSelPort.Text = '0x278' then begin
    iTmpDataPort := DATA2;
    iTmpControlPort := CONTROL2;
  end;

  PortOut(iTmpControlPort, $2D);
  byInValue := PortIn(iTmpDataPort);
  PortOut(iTmpControlPort, $00);
  Memo1.Lines.Add(IntToStr(byInValue));

end;

procedure TForm1.btWriteClick(Sender: TObject);
var
  iTmpDataPort: Integer;
  iTmpControlPort: Integer;
  iOutValue: Integer;
begin
  if cbxSelPort.Text = '0x378' then begin
    iTmpDataPort := DATA1;
    iTmpControlPort := CONTROL1;
  end;
  if cbxSelPort.Text = '0x278' then begin
    iTmpDataPort := DATA2;
    iTmpControlPort := CONTROL2;
  end;

  if TryStrToInt(edWriteValue.Text, iOutValue) then begin
    if (0 <= iOutValue) AND (iOutValue <= 255) then
      PortOut(iTmpDataPort, iOutValue)
    else begin
      ShowMessage('병렬포트로 출력하실 값의 범위는 0부터 255까지 입니다.');
      edWriteValue.SetFocus;
      exit;
    end;

  end
  else begin
    ShowMessage('병렬포트로 출력하실 값은 0부터 255까지 입니다.');
    edWriteValue.SetFocus;
    exit;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Memo1.Clear;
end;

end.


위 소스는 잠에서 깨어 책보고 바로 만든 것입니다. 그래서 맘에 안드는 구석이 많은...깔끔해 보이지 않는 그런 소스입니다...만,
기능적으로 큰 문제는 없습니다.
...회사에서 사용할 때는 좀 더 이쁘게 다듬겠지요...;
배열도 쓰고 하드웨어 자원도 검색하고...등등...;;
아니면 병렬포트를 이용하는 컴포넌트라도 찾아서 사용하겠지요...;;;

여튼, 제가 네이버와 델코에서 엉뚱한 답때문에 삽질한 것이 억울해서 올립니다. 알고보면 아무것도 아닌데 찾아보면 찾기 힘들거나 찾아도 틀린 정보가 많은...그런 것이었습니다.
다른 분들은 저처럼 삽질하지 않으시기를...

by Dark-Ryu | 2009/06/04 00:08 | 델파이 | 트랙백 | 덧글(3)

[2008.04.05] 담에 걸려 눕지도 못하고 있습니다. ㅜ.ㅜ

금요일부터 고생하고 있습니다.
똑바로 누워도 옆으로 누워도 엎드려 누워도 아퍼서 잠을 제대로 못 자고 있습니다. ㅜ.ㅜ
토요일에 가서 침을 맞기는 했는데...한의사 말로는 호흡근 쪽에 침을 한번 더 맞아야 한다는 군요.
월요일에 맞고 출근하면 딱인데...으...

담의 원인은 뭐...항상 그러하듯이 꾸부정한 자세죠.
그런데 컴퓨터...그것도 조그만 노트북으로 주로 작업을 하다보니 좀...;
한의사분이 그러더군요. 접힌 어깨라고...
이번에 담 풀리고 나면 정말정말 주의할 겁니다. 이렇게 고통스럽다니...
한참 이런저런 잘 되는 상황에서 귀한 주말 시간이 날라갔습니다.
으휴...주말이 아니면 프로그램 작업을 할 시간이 없다는 것이 너무너무너무너무 싫습니다.
'더 큰 문제는 그런 상황에서 회사에서 뭐뭐 언제까지 되나요?'
'그럼 지금 할 수 있는 것이 뭔가요?'
따위의 질문을 하는 것이 더 짜증이 납니다.
...그런데 저는 그런 현실 속에서 일해야 하는 것이죠. 월급도 덜 들어오는 상황이라 뭐랄까 의욕이 반토막인데...
뭐...이런저런 짜증때문에 요새 일하기 정말 싫습니다.
회사를 옮기고 싶은 생각이 많이 들지만 ... 참고 있는 중입니다.
한 몇주만 더 고생해보고 심각하게 고민해봐야겠죠.

월급을 180 정도로 떨구고...이제는 100 만원씩만 준 것이 2달 째...노동부에 가기에는 조금 약하겠죠...

by Dark-Ryu | 2009/04/05 19:03 | 근황? | 트랙백 | 덧글(0)

선점형/비선점형 멀티태스킹...그리고 Synchronize

윈도우즈95 이후 현재의 비스타까지의 윈도우즈는 선점형 멀티태스킹을 지원한다.
선점형은 비선점형에 비해 여러가지 장점이 있다고 알려져 있다.
그런데 일반 사람들은 이 둘의 차이를 잘 모르고 '아~ 좋은 거구나' 하고 넘어가는 경우가 많다.
그리고...심지어는 프로그래머조차도 이 둘의 차이를 잘 모르는 경우가 있다.

손전등 한개만 가지고 어두운 곳에서의 야간 공사를 할 경우, 한사람이 손전등을 가지고 작업을 하는 동안 다른 사람들은 작업을 할 수 없을 것이다.
누군가가 작업을 하고 있는데 다른 사람이 손전등 좀 달라고 할 때 '좀 기다려봐 나 아직 안 끝났어' 하고 손전등을 넘기지 않으면 손전등을 가지고 있지 않은 사람은 답답해도 그냥 기다릴 수 밖에 없는 경우가 선점형이다.
누구든 손전등을 먼저 잡은 사람이 장땡인 것이다.
그런데 만약 손전등을 달라고 하는 사람이 사장님이면 어쩔 것인가? 손전등을 줄 수 밖에 없을 것이다. 이것이 비선점형이다. 먼저 손전등을 집었어도 사장님이 달라고 하면 넘겨줘야 하는 것이다.

단일 쓰레드 환경에 익숙한 사람들은 비선점형 멀티태스킹까지는 쉽게 이해한다.
비선점형 멀티태스킹에서 태스크를 어떤 특정 이벤트가 발생했을 때 처리되는 독립적인 함수라는 식으로 생각을 확장하기도 한다. 일단 함수가 호출되면 다른 함수들은 그 함수가 처리되기 전까지는 기다려야 하고 호출된 함수는 다른 함수들을 고려할 필요가 없는 것이다. 비선점형에서의 태스크와 비슷하지 않는가?
그렇지만 선점형 멀티태스킹은 이런 식으로 생각 할 수가 없다.
태스크를 수행하고 있다가도 자신보다 우선순위가 큰 태스크가 제어권을 요청하면 제어권을 넘겨야하는 것이다.
제어권 요청 순서는 동일 우선순위 태스크일 경우에만 중요할 뿐 우선순위가 다르다면 아무런 의미가 없다.

그림을 그리는 태스크와 그림을 액자에 넣어 벽에 거는 태스크가 있다.
직감적으로 알 수 있듯이 그림을 그리는 태스크가 그림을 액자에 넣어 벽에 거는 태스크보다 시간이 더 오래 걸린다.
그런데 만약 그림을 액자에 넣어 벽에 거는 태스크가 우선 순위가 높다면 어떤 일이 벌어질까?
완성되지 않을 그림이 액자에 넣어져 벽에 걸리 수 있을 것이다.

멀티 태스킹에서 이런 문제를 공유자원에 대한 동기화 문제라고 한다.
...어려운 말이다.

일반적으로 델파이의 TComponent는 쓰레드에 대해 안전하지 않다. 델파이의 VCL 중 이 클래스의 후손들도 쓰레드에 대해 안전하지 않다. 쓰레드 내부에서 VCL의 시각적인 요소들을 사용하려고 시도한다면 문제가 발생할 것이다.
이런 문제를 막기 위해서는 쓰레드 동기화를 위해 Critical section 혹은 뮤텍스 등을 이용해 VCL 코드의 일정 부분을 wrapping 해야만 하는데 이런 부분이 있으면 VCL은 눈에 띄게 더 커지고 느려진다.
이런 상황을 피하는 방법으로 TThread 객체의 Synchronize 함수가 제공된다.
이 함수는 쓰레드 내부에서 VCL을 호출할 수 있게 해주는 것으로 쓰레드 local storage에 대해 10배 정도 더 빠른 대안을 제공한다.

'Synchronize는 쓰레드가 일시적으로 애플리케이션의 메인 쓰레드의 일부가 되도록 해준다. synchronize가 호출될 때 메인 쓰레드가 실행되지 않는다. VCL은 다른 어떤 메시지들도 받을 수 없고 그래서 Synchronize가 실행되는 시간 동안 VCL의 속성과 메쏘드에 안전하게 접근하거나 호출할 수 있다.'
...머리가 나쁜 나로써는 이 문장을 그냥 이렇게 이해하는 수밖에 없다.
Synchronize를 호출하면 일시적으로 비선점형처럼 동작한다.

이것이 맞는지는 실험을 해봐야 할 것이다.
.........아직 확신하는 것은 아니라는 소리다.
그런데 여기 글을 쓰는 것은 머리가 나쁜 나로써는 일과 생활에 치여 까먹기 일쑤이기 때문에 기록을 남기는 것이다.
시간나면 확인할 수 있는 프로그램을 짜봐야할 듯...

2009.05.05. 선점형과 비선점형을 반대로 써놓는 큰 실수를 저질렀다...왜 이런 부분은 한글보다 영어가 더 안 헷갈리는지 모르겠다.

by Dark-Ryu | 2009/04/03 09:59 | 델파이 | 트랙백 | 덧글(2)

<< 이전 페이지다음 페이지 >>