掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.30052

処理中に時間遅延を示すメッセージを出力させる方法
投稿者---レイ(2007/04/22 01:32:46)


はじめて投稿させて頂きます。

C言語でLinux(CENTOS)上で動作するコマンドを作る課題に、以下の処理が解らず苦戦しています。
よろしくお願い致します。

[処理内容]
ある任意の処理を行い、やたら処理時間がかかる場合は、「お待ち下さい」を示す "Please Waiting..." を出力させます。処理時間が3秒以上かかる場合は出力を行い、3秒以内であれば出力しないというもので、更に"..."を0.5秒単位に出力させます。

"Please Waiting..." を0.5秒チェックを行いながら出力しつつ、処理を行うということで、処理の中で時間のチェックを行い、毎回出力させるようにするしか方法は無いのでしょうか?それとも、何か標準関数などを利用して登録することで、出力させることが可能になるのでしょうか?


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:処理中に時間遅延を示すメッセージを出力させる方法 30053 επιστημη 2007/04/22 01:50:54
<子記事> Re:処理中に時間遅延を示すメッセージを出力させる方法 30054 かずま 2007/04/22 15:50:48


No.30053

Re:処理中に時間遅延を示すメッセージを出力させる方法
投稿者---επιστημη(2007/04/22 01:50:54)
http://blogs.wankuma.com/episteme/


>"Please Waiting..." を0.5秒チェックを行いながら出力しつつ、処理を行うということで、処理の中で時間のチェックを行い、毎回出力させるようにするしか方法は無いのでしょうか?

それでもいいし、マルチスレッドにしてしまえば処理本体をバックグラウンドに回せます。



この投稿にコメントする

削除パスワード

No.30054

Re:処理中に時間遅延を示すメッセージを出力させる方法
投稿者---かずま(2007/04/22 15:50:48)


Linux の gcc でコンパイルするときは、-lpthread が必要かも。
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

int running;

void *msg_thread(void *p)
{
    usleep(3000000);
    if (!running) return NULL;
    printf("Please wait ...");  fflush(stdout);
    while (running) {
        printf("...");  fflush(stdout);
        usleep(500000);
    }
    return NULL;
}

int main(void)
{
    pthread_t id;

    running = 1;
    pthread_create(&id, NULL, msg_thread, NULL);
    puts("start");
    usleep(5200000); // 長時間の処理
    running = 0;
    puts("\nstop");
    return 0;
}



この投稿にコメントする

削除パスワード

No.30055

Re:処理中に時間遅延を示すメッセージを出力させる方法
投稿者---breakwind4u(2007/04/23 12:41:10)


1) while (!running) のループは、最適化により running の更新が
確認されなくなる場合がある。cond var 使うのが常套。最低でも
volatile で宣言する。

2) sleep/usleep は「最低n秒(μ秒)待つ」であって、最大の方は
規定されない。他の thread がビジーである場合、msg_thread は
最後まで起き上がらないかも。

3) create しておきながら join しないのは、やはり行儀が悪い。



この投稿にコメントする

削除パスワード

No.30057

Re:処理中に時間遅延を示すメッセージを出力させる方法
投稿者---かずま(2007/04/23 20:30:08)


> 1) while (!running) のループは、最適化により running の更新が
> 確認されなくなる場合がある。cond var 使うのが常套。最低でも
> volatile で宣言する。

そうですね。最初は、running を main のローカル変数にして、そのアドレスを
msg_thread の引数に渡して、それを (volatile int *)にキャストして
参照するコードを書いていたんですが、分かりにくいので running を
グローバル変数にしてしまいました。そのときに volatile が落ちたようです。


> 2) sleep/usleep は「最低n秒(μ秒)待つ」であって、最大の方は
> 規定されない。他の thread がビジーである場合、msg_thread は
> 最後まで起き上がらないかも。

msg_thread を先に動かす方法はないかと調べてみたんですが、
pthread_yield なんてないんですね。


> 3) create しておきながら join しないのは、やはり行儀が悪い。

そうですね。join するか、または create 直後に detach するべきでした。


このプログラムは、pthread を使えば、だいたいこんな感じになるよ、という
サンプルを示しただけで、実際に穴のないプログラムを書いたつもりはありません。
pthread_create が成功したかどうかのチェックもないし、2つのスレッドの
出力が混ざり合わないようにロックするなどの対処もしていません。

breakwind4u さんのご指摘に感謝します。元の質問者にも参考になるでしょう。

pthread を使わないとしたら、setitimer かなあ。でも、シグナルハンドラー
の中からメッセージを出力するのは大丈夫かな?


この投稿にコメントする

削除パスワード

No.30058

Re:処理中に時間遅延を示すメッセージを出力させる方法
投稿者---yoh2(2007/04/23 23:27:45)


>pthread を使わないとしたら、setitimer かなあ。でも、シグナルハンドラー
>の中からメッセージを出力するのは大丈夫かな?

この部分だけに反応。
同期用の変数を使う方法には自信がない。シグナルの使い方は慣れているけど、シグナル
ハンドラからprintf()を呼び出すのは御法度だからなぁ、という場合 (随分限定的だな……)、

1. 最初にpthread_sigmask()ですべてのシグナルをブロックする。
2. シグナル受信専用スレッド(sigwait()でループするスレッド)を作る。

こうすればシグナルアンセーフな関数を呼び出し放題なシグナルハンドラもどきが作れます。
でもリエントラントじゃない関数を呼び出すのは危険なままなので注意。


この投稿にコメントする

削除パスワード

No.30056

Re:処理中に時間遅延を示すメッセージを出力させる方法
投稿者---breakwind4u(2007/04/23 12:44:51)


4) usleep は 1000000 以上の値をエラーと考えるシステムもある。
(useconds_t 型は [0,1000000] の範囲の整数を扱うことができる
符号なし整数型である)。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧