HOME 戻る

プログラミング・ガイド1 (C言語フォーム/オブジェクト読み書き)

 
 
C言語プログラムに触れながら、
ポイントオブジェクト読み書きを中心にKCXライブラリの使いかたを解説します。  
 

 
【 1. プログラムの基本構成 】
 
  以下のプログラムが基本構成です。これをベースにアプリケーションを作成していきます。
  #include <karacrix.h>
  main( argc, argv )
  int   argc;
  char *argv[];
  {
      kcxinit( argc, argv );
  }
 《解説》
  (1) karacrix.h は、どこにあるのでしょうか?
      karacrix.h は、プログラムをコンパイルする毎に一時的に自動生成されてそれを使います。 
      自動生成すると言っても元ファイルがあります。それは、
      karacrixXXX(KaracrixBuilderのディレクトリ)/sys/sinc/kcxux_program.h です。
      これがプログラム毎に編集(制御か印刷用かで少々情報追加)されて、karacrixXXX/sys/stmp/karacrix.h に置かれます。
      なお、karacrixXXX/sys/stmp/karacrix.h は KaracrixBuilder が起動する度に初期削除されます。
  (2) argc,argv は、必要なのでしょうか?
      argc,argv は、KaracrixBuilder がプログラムの起動に必要なデータを与えるものです。
      kcxinit(argc,argv); に渡します。
  (3) kcxinit(argc,argv); は、必要なのでしょうか?
      kcxinit() は、KaracrixBuilder側とプログラムの結合に必要不可欠なものです。
      オブジェクト等のアドレス含め多くの情報をプログラムのライブラリに初期値として渡しています。
  (4) kcxinit(argc,argv); を記述する場所はどこでしょうか?
      main() 関数の最先頭位置になければなりません。
 

 
 
【 2. オブジェクトとは 】
 
  監視、計測、制御等の対象を総称してオブジェクトと呼んでいます。
  センサ等のデバイスはポイント・オブジェクトと呼んでいます。
  制御プログラムはプログラム・オブジェクトと呼んでいます。
  オブジェクトはシステム上で記号(ID)化して扱います。
  では、そのオブジェクトのシステム上の実態は何でしょうか。
  それはメモリです。例えば以下の(ポイントオブジェクト)ファイルの内容を見てみてください。
  karacrixXXX/usr/sdx/sys_S_obj_point.edt
  KaracrixBuilder 上で使用しているポイントのデータらしきものが並んでいる事が分かると思います。
  ファイルには、属性とそのデータが記述されています。
  このファイルの内容が KaracrixBuilder 実行時にオブジェクト用のメモリにコピーされます。
  また、メモリにはファイルの内容以外にポイントの現在状態値等を格納する領域も加わります。
  そしてこのメモリ上のデータをKaracrixBuilderや制御プログラムがお互い読み書き使用するのです。
 

 
 
【 3. ポイント状態の読み書き 】
 
  ポイントオブジェクトの状態を読み書きする場合、ライブラリを使用します。
  ライブラリは、KaracrixBuilder専用のKCXライブラリと言うものです。
  KCXライブラリは、簡単にはユーザデータと上記解説オブジェクトメモリとの橋渡しを行うものです。
  ポイント状態を読み書きする場合の手順は、以下の2つです。
  1. ポイントをオープンし ID を取得する。
  2. 取得した ID に対して読み書きを行う。
  #include <karacrix.h>
  main( argc, argv )
  int   argc;
  char *argv[];
  {
    int    objid,status;
    int    idata;   
    double fdata;   
      kcxinit( argc, argv );
      objid  = kcxobj_open( "di001" );
      status = kcxobj_stat_ird( objid, &idata );
  }
 《解説》
  (1) 作業メモリの宣言
      オブジェクトIDと関数の戻り値を保存する整数 objid と status を宣言
      整数ポイント状態値を保存する整数 idata を宣言
      実数ポイント状態値を保存する実数 fdata を宣言
  (2) オブジェクトIDの取得
      objid = kcxobj_open( "di001" );
      で行っています。
      kcxobj_open() に与える引数は、オブジェクトID名という文字列です。
      成功すると関数の返り値として正の整数値が戻って来ます。
      この返り値は ID と呼んでいますが、上記解説オブジェクトメモリのアドレスみたいなものでシステム内部配列値を示しています。
 
  取得した ID に対して読み書きを行う場合、ポイントのデータの型に注意する必要があります。
  ポイントには、以下に示すデータ型と言うものがあります。
  またデータ型別に使用する関数も異りますのでご注意ください。
  覚え方↓
  データ: アナログは実数、それ以外は整数。
  関数名: _xxx 部の i は整数、f は実数。rd は読(read) wt は書(write)。
 
 
ポイントの種別   データ型(状態値)   読み書き関数名
  接点入力(DI)     整数(int)     kcxobj_stat_ird()  
  接点出力(DO)     整数(int)     kcxobj_stat_iwt()  
  カウント入力(PI)     整数(int)     kcxobj_stat_ird()  
  アナログ入力(AI)     実数(double)     kcxobj_stat_frd()  
  アナログ出力(AO)     実数(double)     kcxobj_stat_fwt()  
 
  以下に、ポイント状態を読み込み、また書き込むサンプルを示します。
  KaracrixBuilderの状態一覧画面や監視画面を見ながらプログラム結果見ると良いでしょう。
  なおこのサンプルで注意して頂きたいのは、接点出力やアナログ出力のポイントに対して出力つまり、
  kcxobj_stat_iwt()やkcxobj_stat_fwt()を実行してもリモートI/O装置等の出力デバイスが動作するものではありません。
  上記解説オブジェクトメモリの状態値が変わる(監視画面等には反映)だけです。
  実際の装置出力デバイスを制御するには、装置に対して別途装置に合った操作コマンドを送る必要があります。
  #include <karacrix.h>
  main( argc, argv )
  int   argc;
  char *argv[];
  {
    int    objid,status;
    int    idata;   
    double fdata;   
      kcxinit( argc, argv );
      objid  = kcxobj_open( "di001" );
      status = kcxobj_stat_ird( objid, &idata );
      objid  = kcxobj_open( "di001" );
      status = kcxobj_stat_iwt( objid, 0      );
      objid  = kcxobj_open( "do001" );
      status = kcxobj_stat_ird( objid, &idata );
      status = kcxobj_stat_iwt( objid, 1      );
      objid  = kcxobj_open( "pi001" );
      status = kcxobj_stat_ird( objid, &idata );
      status = kcxobj_stat_iwt( objid, 9999   );
      objid  = kcxobj_open( "ai001" );
      status = kcxobj_stat_frd( objid, &fdata );
      status = kcxobj_stat_fwt( objid, 3.14   );
      objid  = kcxobj_open( "ao001" );
      status = kcxobj_stat_frd( objid, &fdata );
      status = kcxobj_stat_fwt( objid, 31.4   );
  }
 《解説》
  (1) objid = kcxobj_open() を何回も繰り返してよいのでしょうか?
      kcxobj_open() はリソースを溜め込むものではありません。
      アドレス(配列値)みたいなもので ID を返しているだけです。
      ですので例えば同じオブジェクトID名を何回オープン(kcxobj_open)しても構いません。
      但し、kcxobj_open() は、オブジェクトID名をメモリの上から文字検索するので軽負荷ではありません。
      この場合、保存した ID を再使用するようなプログラムにした方が良いと思います。 
  (2) kcxobj_stat_ird( objid, &idata ) のデータ引数
      整数型変数のアドレスを指定します。idata には、ポイントの状態値が入ります。 
  (3) kcxobj_stat_iwt( objid, 1 ) のデータ引数
      整数値あるいは整数型変数を指定します。ポイントの状態値として設定されます。 
  (4) kcxobj_stat_frd( objid, &fdata ) のデータ引数
      実数型変数のアドレスを指定します。fdata には、ポイントの状態値が入ります。 
  (5) kcxobj_stat_fwt( objid, 3.14 ) のデータ引数
      実数値あるいは実数型変数を指定します。ポイントの状態値として設定されます。 
  (6) status = kcxobj_stat_xxx( ... ) 関数の返り値について
      引数を正しく使用している限りエラーは返りません。CPU 環境の影響を受けるものではありません。
 

 
 
【 4. ポイント状態の読み書き関数の使われ方 】
 
  上記説明したポイント状態の読み書き関数の使われ方を、簡単に紹介します。
  ポイント状態の読み込み関数は、ユーザの制御プログラム以外にも使われています。
  例えば、監視画面、計測トレンド画面、状態一覧画面などの状態表示に使用されています。
  CRTディスプレー画面は勿論のことWEB画面用にも応用されています。
  いずれも、kcxobj_stat_ird() kcxobj_stat_frd() 関数を使用して状態を得ています。
  監視画面では、関数より得た結果を元に、CADで設定された方法に従って絵表示しています。
  トレンド画面でも、これを元に、折れ線グラフを描いています。
  また、状態表示のもの以外にもこの関数は使われています。
  これには、状態値を定期的に保存する計測記録ロガーが当てはまります。
  この様に、この読み込み関数は、KaracrixBuilder 内で広く使われています。
 
  しかしながら、書き込み関数は、ユーザによる制御プログラムでしか使用しません。
  それは、ポイントの状態を知り得るのはユーザが作る通信プログラム内しかないためです。
 

 
 
【 5. ポイント汎用属性と警報状態の読み書き 】
 
  ポイントには属性があります。
  そして、これらの読み書きにもKCXライブラリが使われます。
  現在のところ以下のものが準備されています。
 
  A. 汎用属性値
    kcxobj_atbut_ird( objid, no/*1-8*/, &idata ); /*整数属性値の読込*/
    kcxobj_atbut_iwt( objid, no/*1-8*/, idata  ); /*整数属性値の書込*/
    kcxobj_atbut_frd( objid, no/*1-8*/, &fdata ); /*実数属性値の読込*/
    kcxobj_atbut_fwt( objid, no/*1-8*/, fdata  ); /*実数属性値の書込*/
    kcxobj_atbut_crd( objid, no/*1-4*/, cdata  ); /*文字属性値の読込(半角63文字迄)*/
    kcxobj_atbut_cwt( objid, no/*1-4*/, cdata  ); /*文字属性値の書込(半角63文字迄)*/
  B. 警報状態値 (書込はプログラムS1も共有しているので要注意)
    kcxobj_alm_stat_ird( objid, &idata ); /*警報状態値(整数)の読込*/
    kcxobj_alm_stat_iwt( objid, idata  ); /*警報状態値(整数)の書込*/
  C. ロック状態値
    kcxobj_lock_ird( objid, &idata ); /*ロック状態値(整数)の読込*/
    kcxobj_lock_iwt( objid, idata  ); /*ロック状態値(整数)の書込*/
  D. 通信状態値 (書込はプログラムS1も共有しているので要注意)
    kcxobj_online_ird( objid, &idata ); /*通信状態値(整数)の読込*/
    kcxobj_online_iwt( objid, idata  ); /*通信状態値(整数)の書込*/
 
  使用方法はポイント状態の読み書きの時と同じで以下の通りです。
  1. ポイントをオープンし ID を取得する。
  2. 取得した ID に対して読み書きを行う。
  #include <karacrix.h>
  main( argc, argv )
  int   argc;
  char *argv[];
  {
    int    objid,status;
    int    idata;   
    double fdata;
    char   cdata[64];
      kcxinit( argc, argv );
      objid  = kcxobj_open( "di001" );
      status = kcxobj_atbut_ird( objid, 1, &idata ); /*汎用整数属性1取得*/
      status = kcxobj_atbut_frd( objid, 2, &fdata ); /*汎用実数属性2取得*/
      status = kcxobj_atbut_crd( objid, 4, cdata  ); /*汎用文字属性4取得*/
      status = kcxobj_atbut_iwt( objid, 5, 2000   ); /*汎用整数属性5に2000書込例*/
      status = kcxobj_atbut_fwt( objid, 6, 1.23   ); /*汎用実数属性6に1.23書込例*/
      status = kcxobj_atbut_cwt( objid, 1, "日本" ); /*汎用文字用属性1に「日本」書込例*/
      idata = 1234
      fdata = 3.14;
      status = kcxobj_atbut_iwt( objid, 7, idata );  /*汎用整数属性7に1234書込例*/
      status = kcxobj_atbut_fwt( objid, 8, fdata );  /*汎用実数属性8に3.14書込例*/
      status = kcxobj_alm_stat_ird( objid, &idata ); /*警報状態値(整数)の読込*/
      status = kcxobj_alm_stat_iwt( objid, 1 );      /*警報状態値(整数)に1(ON)書込例*/
      idata = 0;
      status = kcxobj_alm_stat_iwt( objid, idata );  /*警報状態値(整数)に0(OFF)書込例*/
      status = kcxobj_lock_wrt( objid, 1 );          /*ロック状態値(整数)の1(ON)書込*/
      status = kcxobj_lock_ird( objid, &idata );     /*ロック状態値(整数)の読込*/
      status = kcxobj_online_ird( objid, &idata );   /*通信状態値(整数)の読込*/
  }
 《解説》
  (1) 汎用文字属性の文字長について
      読み書き出来る文字長は半角63文字迄です。全角で31文字迄となります。
      文字変数を宣言する場合の長さは、63+終端(0:NULL)で、64文字分必要になります。
 
  ◯汎用属性読み書き関数 ( kcxobj_atbut_ird(),iwt(),frd(),fwt(),crd(),cwt() )
  汎用属性はGUI設定画面よりプログラムに情報を与える為だけのものではありません。
  プログラム間で汎用属性を用いてデータのやり取り(読み書き)に使っても構いません。
  汎用属性は、システム内に汎用属性数(整数8/実数8/文字4[63])×ポイント数分
  存在する大きな共有メモリと考えても良いです。
  使用しているポイントに関するデータをそのポイントの属性に使用するのは勿論ですが、
  属性数不足の場合に他の空いているポイントのものを使用するなど使いかたは自由です。
  汎用属性のデータは、監視画面に表示させることが出来ます。
  監視画面は、ポイントの状態のみが表示される訳ではありません。
  プログラムで演算した整数や実数、また文字列を監視画面データとして使用できます。
  1. 表の表示 : 監視画面に表の枠等を作成し任意の数値や文字を表示させられます。
  2. 時刻表示 : 自由な書式で時刻を文字列にするなどして表示できます。
 
  ◯警報読み書き関数 ( kcxobj_alm_stat_ird(),iwt() )
  特にアナログに於てヒステリシス(不感帯)を考慮した警報検出のプログラムは複雑です。
  この時、プログラムS1(併用)の警報機能を利用するとこの手間が省け便利です。
  プログラムS1は、kcxobj_alm_stat_iwt()を使用して警報状態を設定しています。
  これを、kcxobj_alm_stat_ird()を使用して利用します。
  またこの方式を使用すると、アナログ的な警報状態がデジタル的なON/OFF警報
  の状態で利用処理出来るようになりますのでプログラムの単純化に期待できます。
 
  ◯ロック読み書き関数 ( kcxobj_lock_ird(),iwt() )
  プログラムS1では、ロックをメールの送信の許可に使用していますが、
  使用目的が決められている訳ではありません。
  何かを一時的に止めたり解除したりする汎用的なものです。
 
  ◯通信読み書き関数 ( kcxobj_online_ird(),iwt() )
  プログラムS1を併用させて自動制御プログラムを組む場合、
  制御の対象ポイントが正常通信接続されているのか、
  あるいはエラーで通信断されているのかを知る必要があります。
  プログラムS1では、kcxobj_online_iwt()を使用して通信状態を設定しています。
  これを、kcxobj_online_ird()を使用して目安に知ることが出来ます。
  目安とは、通信状態は通信状況に合わせ頻繁に変化する非継続的なもので注意が必要な為です。
  確実な自動制御を行う場合には、対象ポイント操作後その状態を再確認をするようにして下さい。
 
 

 
 
【 6. 装置出力へのポイント操作 】
 
  システムにおけるポイント操作の入力方法には以下があります。
  1. 画面における手動操作
  2. スケジューラ操作
  3. WebブラウザやEメールからの遠隔操作
  4. プログラム操作 (次項説明)
  以上の4つです。
  そして入力されたポイント操作のデータをプログラムで取り出します。
  具体的には、kcxobj_sndstat_fromkcx() という関数でデータを取り出します。
  データをプログラム以外で取り出す方法はありません。
  それでは、ポイント操作のデータはどう流れているのでしょうか。
  データの流れは単純です。
  KaracrixBuilder では、ポイント操作データを格納するFIFOスタックメモリが1つあります。
  ポイントを操作するとそのデータは、FIFOスタックメモリに積まれます。
  これを、kcxobj_sndstat_fromkcx() という関数で取り出し処理します。
  ※FIFOとは、FirstInFirstOutの頭文字で、最初に入ったものを最初に出すの意です。
      FIFOスタックサイズの容量は、KaracrixBuilder24Aの場合、200です。
      なおデータを取り出さなかった等の未処理のものは古いものから内部削除されます。
 
  ポイント操作のデータを取得処理するプログラムの作り方は自由ですが、
  複数のマルチプログラムから kcxobj_sndstat_fromkcx() を使用する事は考えない方が良いでしょう。
  通常、リモートI/O装置と通信するプログラム内に kcxobj_sndstat_fromkcx() を使用します。
  ポイント操作データの存在を検出したら、速やかにリモートI/O装置の出力を操作しなければならなくなるためです。
 
  以下に、ポイント操作のデータを取得する部分のみのサンプルプログラムを示します。
  ポイント操作データの存在を検出すると、データの型別にプログラムスイッチします。
  現在のところ、整数の場合接点出力(DO)で、実数の場合アナログ出力(AO)と決めて構いません。
  ポイントのIDとデータが、kcxobj_sndstat_fromkcx() より取得できていますので、
  リモートI/O装置に操作コマンドを送るなど適宜処理します。
 
  リモートI/O装置に操作コマンドを送信後、
  装置から正常通信応答があった。あるいは更に、
  リモートI/O装置に状態取得コマンドを送り、操作したものの設定の確認が得られた。
  この場合に、
  出力型ポイントの状態値を kcxobj_stat_iwt() や kcxobj_stat_fwt() を使用して
  ポイントオブジェクトの正式な現場状態としてデータ設定すると良いでしょう。
  #include <karacrix.h>
  main( argc, argv )
  int   argc;
  char *argv[];
  {
    int         objid;
    KcxIntFlt_t udata;
      kcxinit( argc, argv );
      for(;;){
        switch( kcxobj_sndstat_fromkcx( &objid, &udata ) ){
        case KcxINTEGER: /*整数型ポイント*/
             /* ------------------------------------------------------------*/
             /* 通常ここにリモートI/O装置へのコマンド送信プログラム書きます */
             /* ------------------------------------------------------------*/
             kcxobj_stat_iwt( objid, udata.i );  /* ← ポイント状態確定設定例 */
             break;
        case KcxFLOAT:   /*実数型ポイント*/
             /* ------------------------------------------------------------*/
             /* 通常ここにリモートI/O装置へのコマンド送信プログラム書きます */
             /* ------------------------------------------------------------*/
             kcxobj_stat_fwt( objid, udata.f );  /* ← ポイント状態確定設定例 */
             break;
        case KcxNULL:    /*データ無し*/
        default:
             break;
        }
        sleep( 1 );
      } 
  }
 《解説》
  (1) 作業メモリの宣言
      ポイントの操作値を取得する為の共用体名 KcxIntFlt_t 型の udata を宣言
      KcxIntFlt_t は、整数と実数両方が扱える共用体で、karacrix.h の中に定義されています。
  (2) kcxobj_sndstat_fromkcx() 関数の返り値
      FIFOスタックメモリ内にポイント操作データが存在しない場合、KcxNULL が返ります。
      データが存在する場合、ポイントのデータ型別に返り値が異ります。
      整数型ポイントの場合 KcxINTEGER が、実数型の場合 KcxFLOAT が返ります。
      KcxINTEGER KcxFLOAT KcxNULL は、karacrix.h の中に定義されています。
  (3) 取得した objid と udata パラメータ
      objid には、操作ポイントのオブジェクトIDが入っています。
      udata には、操作ポイントのデータが入っています。
      udata だけでは、整数か実数かどちらのデータかは見分けが付けません。
      ポイントのデータ型別に、 udata.i で整数が、udata.f で実数を取り出せます。 
  (4) sleep( 1 ) の意味
      1 秒間プログラムに待ちを入れると言う意味です。
      もしこのsleep()文を使用せずプログラムにウエイトを入れなかった場合で、
      FIFOスタックメモリにデータが無いとfor()文がものすごい早さで空回りします。
      ただこの空回り、CPUに対して負荷が軽いのではなく大変重いものになります。
      アプリケーションとしては仕事はしていませんが、
      for()文とswitch()文の単純判断だけの処理を忠実に膨大に行うからです。 
      アプリケーションに必要な時間だけを与え、後はウエイトさせる様にする方が良いでしょう。
 

 
 
【 7. プログラムによるFIFOスタックメモリ書込 (5.装置出力へのポイント操作続編) 】
 
  kcxobj_sndstat_fromkcx()を使ってFIFOスタックメモリより操作データを取得し、
  リモートI/O装置を制御している他の(並列実行)プログラムが動作しているとします。
  このプログラムに対し操作データを送りたいプログラムは、
  FIFOスタックメモリに操作データを書き込む必要があります。
 
  プログラムによってポイントの操作データをFIFOスタックメモリに書き込む場合、
  kcxobj_sndistat_tokcx()と kcxobj_sndfstat_tokcx() という関数を使用します。
  kcxobj_sndistat_tokcx()は、整数型ポイントで使用します。
  kcxobj_sndfstat_tokcx()は、実数型ポイントで使用します。
  関数名は、..sndistat.. と ..sndfstat.. の違いで、 i は整数、 f は実数を示します。
  引数はともに2つで、1番目にオブジェクトID、2番目にデータとなります。
  以下にサンプルプログラムを示します。
  #include <karacrix.h>
  main( argc, argv )
  int   argc;
  char *argv[];
  {
    int objid;
      kcxinit( argc, argv );
      objid = kcxobj_open  ( "do001"     );
      kcxobj_sndistat_tokcx( objid, 1    );
      objid = kcxobj_open  ( "ao001"     );
      kcxobj_sndfstat_tokcx( objid, 3.14 );
  }
 《解説》
  (1) do001 の操作
      ポイント操作のデータ 1 をFIFOスタックメモリに書き込みました。
      デジタル型のポイントの場合、1 が ON で 0 が OFF という決まりに統一しています。
  (2) ao001 の操作
      ポイント操作のデータ 3.14 をFIFOスタックメモリに書き込みました。
  (3) kcxobj_sndistat_tokcx() 関数の返り値について 
      ここでは、関数実行の成功失敗の返り値は見ていません。 成功したとしても、
      そのデータが回り回ってリモートI/O装置の出力を操作した結果で無いためです。
 

 
 
【 8. プログラムの機能分散について 】
 
  KaracrixBuilder 上で稼働するプログラムに必要な機能には以下のものがあります。
  1. 通信(機能)プログラム
  2. 警報(機能)プログラム
  3. 制御(機能)プログラム
  のおおよその3種類で、それぞれ以下のような役割が考えられます。
  通信プログラムは、リモートI/O装置との通信を行いポイント等の状態を管理する。
  警報プログラムは、異常を検出し、記録しブザーやメールなど使い外部に警報を知らせる。
  制御プログラムは、ケースバイケース目的別の自動化を図る。
 
  具体的なプログラムのまとめ方、つまり書き方は、
  上記3つのプログラム機能を1本のプログラムに書いても良いですし、
  3本あるいはそれ以上に機能分散させて書いても良いものです。
  前者のことをシングルプロセスプログラム、後者をマルチプロセスプログラム構成と言います。
 
  但しここでどちらにするかで、システムの性格が結構分かれてしまいます。
  一度プログラムを作成し始めると、後でのシステム変更はかなりしんどいものになります。
  ですので出来れば最初に方式を決めたいところです。
  しかしながら仕様は使いながら向上しますのでそうとも言えないため難しさがあります。
 
  プログラムの作り方で一般的に以下の事が言えますので参考にして経験積んでください。
  ◯ シングルプロセスプログラム
    【長所】 リアルタイム処理化させやすい。
    【短所】 ソースが巨大化し視認性が低下、複雑なため改造も困難になりやすい。
  ◯ マルチプロセスプログラム
    【長所】 ソースが比較的小さくまとまり管理しやすい。
    【短所】 リアルタイム処理化に問題が生じる可能性がある。
 
  上記の比較で、特に目を引くのがリアルタイム化です。
  リアルタイムの事しか記述していないのでそうなりますが、これは条件付きです。
  このことは、冒頭に説明しておくべきものでした。
  上記比較は、1つの仕事をシングルかマルチで実行させるかの場合のものです。
  まったく異る仕事であるならば、それら複数をシングルにまとめることは無意味です。
 
  1つの仕事をマルチで実行させた場合必ずその間でデータのやり取りが発生します。
  LinuxやUNIXの世界では、ここに使うもののことをプロセス間通信と言います。
  1つの仕事をマルチプロセス化させられるこのプロセス間通信は立役者です。
  しかし、この立役者を介してデータをやり取りするには時間と負荷を要することになります。
  従って、マルチ化させたプログラムお互いが常時この立役者を凝視させる作りにしません。
  ※常時立役者を凝視させる様な非常に密なものはシングルで作るべきものなのです。
  このためアクセスにタイムラグが発生するので、リアルタイム化が難しいということになるのです。
 
  顕著な影響例として、1秒おきにリレーをON/OFFさせるシステムを考えてみます。
  勿論、他のI/Oポイントの状態管理を行いながら実行するという現実的な条件でです。
  システムに必要なプログラム基本機能は、
  1. 通信(機能)プログラム
  2. 1秒の時間監視を行いON/OFFさせる制御(機能)プログラム
  の2つです。
  これをシングルプロセスプログラムとして作成する場合、
  通信しながら、1秒の時間監視とON/OFF判断させるのか、あるいは、
  1秒の時間監視とON/OFF判断しながら、通信させるのかは別として、
  複雑にはなりますが、1つのプログラム内の事ですから
  最優先事は自己判断で確実にON/OFF処理するプログラムが書けるはずです。
  一方。
  これをマルチプロセスプログラムとして作成する場合、
  通信に関しては、通信のみ行うプログラムが実行、
  制御に関しては、制御のみ行うプログラムが実行するのはシンプルで良いですが、
  制御でON/OFFが決定されたデータを、通信プログラムに送らなければなりません。
  ここでプロセス間通信が発生します。
  ここの例では、上記で述べてきたポイント操作データの転送という事になるので、
  制御側では kcxobj_sndistat_tokcx() データ送信関数の使用、
  通信側では kcxobj_sndstat_fromkcx() データ受信関数の使用になります。
  そして、マルチプロセス化におけるリアルタイムの問題は、
  通信側のプログラムの作りでデータ受信関数をどの頻度で呼んでいるかがキーポイントです。
  もし、1秒間隔で読んでいるとすると、お互いの、
  1(ON/OFF間隔)±1(読取間隔)秒の誤差が生じてリレーがON/OFFされる事になってしまいます。
  もし、待ち無し0秒で読んでいるとするならば、通信プログラムは非常に負荷の重いものになってしまいます。
  ではこの場合、通信プログラムはどのような間隔でデータ受信関数を呼べば良いのでしょうか。
 
  はっきりとした答えはトータルバランスを考えて決めるべきもので一概に言えませんが、
  おおよそ、100msec〜300msec 程の所ではないでしょうか。
  そして最後に結論を述べるならば、
  マルチプロセスで表題の正しく1秒毎にON/OFFさせるとことは困難であることが分かります。
  但し、1秒前後の誤差が許せるのであれば、マルチプロセス構成の方がシンプルで良いものです。
  これが許せないのであれば、シングルプロセス構成で作るのが良いのかもしれません。
 
  以上ここでは、マルチプロセス化での問題の一つを紹介し、
  シングル、マルチとも一長一短があるというお話をしました。
 
 

HOME 戻る