C言語関係掲示板

過去ログ

No636 ファイルの作成確認、プログラムを起動させる常駐型のプログラム

[戻る] [ホームページ]
No.6734

ファイルの作成確認、プログラムを起動させる常駐型のプログラム
投稿者---桂(2003/05/25 13:11:50)


自動的に5分毎にある任意の場所にファイルが作成されているか
チェックしたり、プログラムを起動するプログラムを常駐型で
作りたいのですが。
また、1時間毎に情報を取得する常駐型のプログラムを作りたい
のですが、どのようにすればよいのですか。


/*-------------------------------------*/
#include <stdio.h>
#include <unistd.h>

main()
{
    pid_t    id;
    int    fd, n;

    if ((id = fork()) != -1) {
        if (id == 0) {
            n = sysconf(_SC_OPEN_MAX);
            for (fd = 3; fd < n; fd++)
                close(fd);

            setsid();

            if (execl("起動プログラム","起動プログラム",NULL) == -1)
                exit(1);
        } else {
            exit(0);
        }
    } else {
        exit(1);
    }



No.6781

常駐して処理が継続されない。
投稿者---桂(2003/05/26 15:35:36)


以下のとおり、プログラムを作成し、動かしてみたのですが、
最初の一回目しか動かず、連続して動いてくれません。
常駐もしてくれません。

「プログラム 1 &」で起動しました。

どこが悪いのでしょうか。

#include <stdio.h>
#include <unistd.h>
#include <time.h>

main(argc, argv)
    int  argc ;
    char *argv[] ;
{
    time_t date,s_date,now_date ;
    struct tm *ltime ;
    char  dtime_str[7] ;
    pid_t  id, pid ;
    int    fd, n ;
    int    inte_time ;

    if (argc != 2) {
        printf("インターバル時間を分で指定して下さい。\n") ;
        printf("Usage : %s 5\n",argv[0]) ;
        exit(1) ;
    }

    inte_time = atoi(argv[1]) ;

    if ((id = fork()) != -1) {
        if (id == 0) {
            n = sysconf(_SC_OPEN_MAX) ;
            for (fd = 3; fd < n; fd++)
                close(fd) ;

            /* 起動日時の00:00:00を取得 */
            time(&date) ;
            ltime = localtime(&date) ;
            ltime->tm_sec = 0 ;
            ltime->tm_min = 0 ;
            ltime->tm_hour= 0 ;
            s_date = mktime(ltime) ;

            while (1) {
                time(&now_date) ;
                if (now_date >= s_date + (60 * inte_time)) {
                    ltime = localtime(&now_date) ;
                    strftime(dtime_str, 20, "%y/%m/%d %H:%M:%S", ltime) ;
                    printf("起動 = [%s]\n",dtime_str) ;
                    s_date = now_date ;

                    setsid() ;

                    if (execl("起動コマンド","起動コマンド",NULL) == -1) {
                        printf("コマンド実行エラー (execl)\n") ;
                        exit(1) ;
                    }
                }
            }
        } else {
            exit(0) ;
        }
    } else {
        printf("プロセス生成エラー (fork)\n") ;
        exit(1) ;
    }
}


No.6783

何故、常駐して繰り返してくれないのか
投稿者---桂(2003/05/26 16:53:32)


環境は、HP-UX11.00です。

最初の一回目のexeclは実行されます。
execlで、プログラムもしくは、シェルを実行したのち終わって
しまいます。

どこがわるのか、教えて
下さい。


No.6784

Re:何故、常駐して繰り返してくれないのか
投稿者---物見遊山(2003/05/26 17:23:12)


cronを使うのはダメなの?

No.6785

Re:常駐して処理が継続されない。
投稿者---物見遊山(2003/05/26 17:32:42)


execl(3)の代わりにsystem(3)を使ってみるのはどーでしょう?

No.6787

動いたことには動いたが....
投稿者---桂(2003/05/26 21:24:10)


>起動直後に処理を実行したかったのと、時間間隔、インターバル時間を
任意にしたかったのでcronでの実行は考えていませんでした。

execlやexecvを使うと、1回目と言うか、一発目の流れで、execl等で
指定したプログラムやシェルスクリプトは実行されるのですが、その
直後、呼び出し元である親が終わってしまう。無限ループ状態になら
ない。
systemを使用すると、一応は動きました。

ただ、topで見たとき、実行しているメインプログラムの%wcpu、%cpu
が異常に高いのですが、何が原因なのですか。

systemを使わずに実現することはできないのですか。
また、topで見たときの状態を低くできないのですか。

#include <stdio.h>
#include <unistd.h>
#include <time.h>

main(argc, argv)
    int  argc ;
    char *argv[] ;
{
    time_t date,s_date,now_date ;
    struct tm *ltime ;
    char  dtime[20] ;
    pid_t  id, pid ;
    int    fd, n ;
    int    inte_time ;

    if (argc != 2) {
        printf("インターバル時間を分で指定して下さい。\n") ;
        printf("Usage : %s 5\n",argv[0]) ;
        exit(1) ;
    }

    inte_time = atoi(argv[1]) ;

    if ((id = fork()) != -1) {
        if (id == 0) {
            n = sysconf(_SC_OPEN_MAX) ;
            for (fd = 3; fd < n; fd++)
                close(fd) ;

            /* 起動日時の00:00:00を取得 */
            time(&date) ;
            ltime = localtime(&date) ;
            ltime->tm_sec = 0 ;
            ltime->tm_min = 0 ;
            ltime->tm_hour= 0 ;
            s_date = mktime(ltime) ;

            while (1) {
                time(&now_date) ;
                /* if (now_date >= s_date + (60 * 1)) {*/
                if (now_date >= s_date + (60 * inte_time)) {
                    s_date = now_date ;

                    setsid() ;

                    /* if (execl("起動コマンド","起動コマンド",NULL) == -1) {*/
                    /* if (execv("起動コマンド",NULL) < 0) {*/
                    if (system("起動コマンド") != 0) {
                        printf("コマンド実行エラー (execl)\n") ;
                        exit(1) ;
                    }
                }
            }
        } else {
            exit(0) ;
        }
    } else {
        printf("プロセス生成エラー (fork)\n") ;
        exit(1) ;
    }
}



No.6788

Re:動いたことには動いたが....
投稿者---しんちー(2003/05/26 22:11:01)


>ただ、topで見たとき、実行しているメインプログラムの%wcpu、%cpu
>が異常に高いのですが、何が原因なのですか。

メインは常に time() で時間を取得しつづけてますよね?
sleep() を入れるなどして他のプロセスにも時間を与えてあげてはどうでしょう。

No.6791

Re:動いたことには動いたが....
投稿者---かずま(2003/05/26 22:49:10)


> systemを使わずに実現することはできないのですか。
> また、topで見たときの状態を低くできないのですか。

こんなことがしたいのでしょうか。
#include <stdio.h>
#include <unistd.h>
#include <time.h>

int main(int argc, char *argv[])
{
    time_t date, now_date;
    int    n, fd, inte_time;
    pid_t  pid;

    if (argc != 2)
        printf("Usage : %s 5\n", argv[0]), exit(1);

    inte_time = atoi(argv[1]) * 60;
    time(&date);

    while (1) {
        date += inte_time;
        time(&now_date);
        if (now_date < date)
            sleep(date - now_date);

        pid = fork();
        switch (pid) {
        case -1: perror("fork"); exit(1);

        case 0: /* child */
            n = sysconf(_SC_OPEN_MAX);
            for (fd = 3; fd < n; fd++)
                close(fd);
            setsid();
            if (execl("/usr/bin/cal", "cal", NULL) < 0)
                perror("cal"), exit(1);
            break;
        default: /* parent */
            wait(NULL);
        }
    }
}


No.6794

Re:動いたことには動いたが....
投稿者---shelly(2003/05/27 09:36:21)


元のソースからして違ってるんですが、
「起動直後に処理を実行したかった」とあるので
    time(&now_date);
    if (now_date < date)
        sleep(date - now_date);
    date += inte_time;
の方が要求を満たしている・・・のかな?



No.6800

ありがとうございます。
投稿者---桂(2003/05/27 11:26:54)


ありがとうございます。

かずまさんが述べていることをやりたかったのです。

私が作成したのは、根本的に間違っていました。
かずまさんが書き込みをしてくれたソースと比べてみたら
fork、setsid等などの実行する方法が違いますね。
毎回、実行しないといけなかったのですね。
forkを1回発行すればよいと思っていたが、そうですね、毎回
プロセスを立ち上げるのですから、その都度、forkの実行は必要
でした。