6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ILERPGAdvent Calendar 2024

Day 12

1秒より短い間隔でDLYJOBしたい時のプログラムを作ってみました。

Last updated at Posted at 2024-11-29

はじめに

CLプログラムで処理と処理の間に待ちを作りたい時はDLYJOBコマンドを使います。
DLYJOBコマンドは待機する秒数ないしは再開の時刻を指定することができてとても便利ですよね。
DLYJOBコマンド

ただ、DLYJOBコマンドの最小の待ちインターバルとしては1秒です。
そのため、1秒よりも短いインターバルでの待ちはDLYJOBコマンドでは作れません。
先日1秒よりも短い間隔で待ちを作りたいということがありまして、そのためのプログラムをILE RPGで作ってみました。

pthread_delay_npサブルーチンを使おう

スレッド・プログラミングのサブルーチンとしてpthread_delay_npがありますが、IBM i でもAPIとして用意されています。
pthread_delay_np -要求された間隔のスレッドの遅延

このAPIの入力パラメーターは上記マニュアルによると、C言語のtimespec構造体のアドレスを渡せば良いようですね。
image.png

timespec構造体は以下のようなもののようです。
pthread_delay_npでは、tv_secに待機の整数秒、tv_nsecに小数点以下の秒をナノ秒としてセットする形です。

#include <time.h>
struct timespec {
  time_t tv_sec; /* Seconds.  */
  long tv_nsec;  /* Nanoseconds.  */
};

ILE RPG (Free Form) では以下のデータ構造として定義しました。

dcl-ds timeSpecDs qualified;
  seconds int(10);
  nanoseconds int(10);
end-ds;

作成プログラム

今回作成したプログラムはこんな感じです。
入力パラメーターとして渡された数値を整数と小数点以下に分けて、データ構造timeSpecDsに入れています。
...ロジックはほぼなしですね(汗

DLYJOBNS.RPGLE
      **free
        
        //全体制御
        ctl-opt dftactgrp(*no) main(main) option(*srcstmt) bnddir('QC2LE');

        //メイン・プロシージャー
        dcl-proc main;
          //入出力パラメーター定義
          dcl-pi *n;
            p_seconds packed(8:3);
          end-pi;

          //利用機能プロトタイプ定義
          dcl-pr pthreadDelayNp int(5) extproc('pthread_delay_np');
            *n pointer value;
          end-pr;

          dcl-ds timeSpecDs qualified;
            seconds int(10);
            nanoseconds int(10);
          end-ds;

          //メイン・ロジック
          timeSpecDs.seconds
              = %int(p_seconds);
          timeSpecDs.nanoseconds
              = %int(%dec(%dec(p_seconds) - %dec(%int(p_seconds))) 
              * (10 ** 9));

          pthreadDelayNp(%addr(timeSpecDs));

          return;
        end-proc;

今回はソースをIFS上に置いて、以下のCRTBNDRPGコマンドで作成しました。
IFS上のソースはUTF-8 (CCSID 1208) でしたので、TGTCCSIDパラメーターを明示指定しています。

CRTBNDRPG PGM(PVSONE/DLYJOBNS) SRCSTMF('/home/NAKAMURA/QRPGLESRC/DLYJOBNS.RPGLE') DFTACTGRP(*NO) DBGVIEW(*SOURCE) TGTCCSID(5035)

プログラムのテスト

DLYJOBNSプログラム実行前後の時刻をミリ秒までの17桁 (YYYYMMDDhhmmsssss) をDSPLY命令で出すILE RPGプログラムを作って実行してみました。
(ちなみに中で使用しているプログラムGETCURTIMEはRTVSYSVAL SYSVAL(QDATETIME) の値をミリ秒までにした値を返すものです。)

DLYTEST.RPGLE
      *free

        //全体制御
        ctl-opt dftactgrp(*no) main(main);

        //メイン・プロシージャー
        dcl-proc main;
          //入出力パラメーター定義
          dcl-pi *n;
            p_seconds packed(8:3);
          end-pi;

          //プロトタイプ定義
          dcl-pr GETCURTIME extpgm('GETCURTIME');
            *n char(17);
          end-pr;

          dcl-pr DLYJOBNS extpgm('DLYJOBNS');
            *n packed(8:3);
          end-pr;

          //ローカル変数
          dcl-s time char(17);
          dcl-s msg char(50);

          //メイン・ロジック
          callp GETCURTIME(time);
          msg = 'DELAY START ' + time;
          dsply msg;

          callp DLYJOBNS(p_seconds);

          callp GETCURTIME(time);
          msg = 'DELAY END   ' + time;
          dsply msg;

          return;
        end-proc;

時刻取得プログラムとDSPLY命令の実行で若干時間がかかっていますが、一応それっぽい時間だけDLYJOBNSで待ってくれていそうですね!

image.png

ちなみに、前述のpthread_delay_npのマニュアルには

Although time is specified in seconds and nanoseconds, the system has approximately millisecond granularity. Due to scheduling and priorities, the amount of time you actually wait might be slightly more or less than the amount of time specified.

とありました。ナノ秒の指定ですがミリ秒の粒度ということです。
あくまでおおよそで待ってくれる感じですが、IBM i で非常にちょっとした待ちを作りたい時の参考になればと思います。

6
1
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?