ショッピングモール  Automotive / Motorcycles ( Pictorial )


掲示板利用宣言

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

 私は

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

掲示板1

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

No.5303

スレッドでの複数タイマー起動について
投稿者---y(2006/01/20 12:51:46)


cygwinで動作させております。
シグナルを利用して複数のタイマー処理を行いたいのですが
下記のコードでは、sigaction()で上書きされてしまいます。
原因の指摘をお願いします。


#include<pthread.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include<time.h>
#include<signal.h>
#include <errno.h>

pthread_mutex_t mutex;                  /* ミューテックス        */

int main(void);
void* func1(void*   pParam);
void* func2(void*   pParam);
void handler1(int   signum);
void handler2(int   signum);
int timer_main1(void);
int timer_main2(void);

typedef struct {
    /* メッセージの先頭はかならずlong int型でなければならない */
    long int type;
    void *data;
}MSG;
typedef struct{
    char name1[16];
    char name2[16];
    char name3[16];
}MSGDATA;

timer_t timerId1;
timer_t timerId2;

void handler1(int   signum)
{

    printf("handler1 start signum=[%d]\n", signum);
    timer_main1();
    return;
}
void handler2(int   signum)
{
    printf("handler2 start signum=[%d]\n", signum);
    timer_main2();

    return;
}

int timer_main1(void)
{
    int i;
    struct itimerspec   itval;

    printf("timer_main1 start\n");

    itval.it_interval.tv_sec = 0;   /* タイマー周期(秒)設定    */
    itval.it_interval.tv_nsec = 0;  /*    タイマー周期(ナノ秒)設定   */
    itval.it_value.tv_sec = 1;  /*    タイマー時間(秒)設定  */
    itval.it_value.tv_nsec = 0; /*   タイマー時間(ナノ秒)設定  */

    /*  タイマー設定                */
    if(timer_settime(timerId1, 0, &itval, NULL) == -1)
    {
        perror("timer_settime");
    }
    printf("timer_main1 end\n");
    return 0;
}
int timer_main2(void)
{
    int i;
    struct itimerspec   itval;

    printf("timer_main2 start\n");
    itval.it_interval.tv_sec = 0;   /* タイマー周期(秒)設定    */
    itval.it_interval.tv_nsec = 0;  /*    タイマー周期(ナノ秒)設定   */
    itval.it_value.tv_sec = 5;  /*    タイマー時間(秒)設定  */
    itval.it_value.tv_nsec = 0; /*   タイマー時間(ナノ秒)設定  */

    /*  タイマー設定                */
    if(timer_settime(timerId2, 0, &itval, NULL) == -1)
    {
        perror("timer_settime");
    }
    printf("timer_main2 end\n");
    return 0;
}

void* func1(void*   pParam)
{
    int i;
    pthread_t   tid1;
    struct sigaction    sigact1;

    sigact1.sa_handler = handler1;
    sigact1.sa_flags = 0;
    sigemptyset(&sigact1.sa_mask);
    if(sigaddset(&sigact1.sa_mask, SIGUSR1)){
        perror("failed to sigaddset");
    }
    /*  ハンドラ設定                */
    if(sigaction( SIGALRM, &sigact1, NULL) == -1)
    {
        perror("sigaction");
    }
    /*  タイマー作成                */
    if(timer_create( CLOCK_REALTIME, NULL, &timerId1) == -1)
    {
        perror("timer_create");
    }

    timer_main1();

    return NULL;
}

void* func2(void*   pParam)
{
    int i;
    struct sigaction    sigact2;

    sigact2.sa_handler = handler2;
    sigact2.sa_flags = 0;
    sigemptyset(&sigact2.sa_mask);
    if(sigaddset(&sigact2.sa_mask, SIGUSR2)){
        perror("failed to sigaddset");
    }
    /*  ハンドラ設定                */
    if(sigaction( SIGALRM, &sigact2, NULL) == -1)
    {
        perror("sigaction");
    }
    /*  タイマー作成                */
    if(timer_create( CLOCK_REALTIME, NULL, &timerId2) == -1)
    {
        perror("timer_create");
    }

    timer_main2();

    return NULL;
}

int main(void)
{
    pthread_t   tid1;
    pthread_t   tid2;

    pthread_mutex_init(&mutex,NULL);        /*  ミューテックス初期化        */
                                            /*  スレッド1生成            */
    if(pthread_create(&tid1,NULL,func1,NULL) != 0)
    {
        perror("pthread_create");
    }
                                            /*  スレッド2生成            */
    if(pthread_create(&tid2,NULL,func2,NULL) != 0)
    {
        perror("pthread_create");
    }
    while(1)sleep(1);

                                            /*  スレッド1終了待ち   */
    if(pthread_join(tid1,NULL) != 0)
    {
        perror("pthred_join");
    }
                                            /*  スレッド2終了待ち   */
    if(pthread_join(tid2,NULL) != 0)
    {
        perror("pthred_join");
    }

    pthread_mutex_destroy(&mutex);      /*    ミューテックス破棄         */
                                            /*  ただし、Linuxの実装では意味  */
                                            /*  がないようである      */
    
    return 0;
}




この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:スレッドでの複数タイマー起動について 5321 かずま 2006/01/23 16:33:55


No.5321

Re:スレッドでの複数タイマー起動について
投稿者---かずま(2006/01/23 16:33:55)


> シグナルを利用して複数のタイマー処理を行いたいのですが
> 下記のコードでは、sigaction()で上書きされてしまいます。
> 原因の指摘をお願いします。

シグナルは、スレッドごとではなく、プロセスごとに処理されるはずなので、
ひとつのシグナル SIGALRM に対して、sigaction で 2回ハンドラを設定
しても、最後の設定しか有効ならないからでしょう。

次のようなコードではダメでしょうか?
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>

int running;

void handler1(int signum)
{
    printf("handler1 start signum=[%d]\n", signum);
}

void handler2(int signum)
{
    printf("handler2 start signum=[%d]\n", signum);
}

void *func1(void *param)
{
    while (running) {
        usleep(1000000);
        handler1(SIGUSR1);
    }
    return NULL;
}

void *func2(void *param)
{
    while (running) {
        usleep(3000000);
        handler2(SIGUSR2);
    }
    return NULL;
}

int main(void)
{
    pthread_t tid1, tid2;

    running = 1;
    if (pthread_create(&tid1, NULL, func1, NULL) != 0) {
        perror("pthread_create"); return 1;
    }
    if (pthread_create(&tid2, NULL, func2, NULL) != 0) {
        perror("pthread_create"); return 1;
    }
    while (getchar() != 'q') ;
    running = 0;
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    return 0;
}



この投稿にコメントする

削除パスワード

No.5349

Re:スレッドでの複数タイマー起動について
投稿者---y(2006/01/26 17:23:43)


かずま様

//シグナルは、スレッドごとではなく、プロセスごとに処理されるはずなので、
>>
以下が勉強不足でした。
 1プロセスとスレッドの違いは?
 2シグナルがどの単位で動いているのか?
 参考URL:
  http://tooljp.com/qa/C4104E55B4914C7449256A9F001CA896.html


//ひとつのシグナル SIGALRM に対して、sigaction で 2回ハンドラを設定
//しても、最後の設定しか有効ならないからでしょう。
>>
複数シグナルを指定させた場合、タイムアウト通知はそれぞれ実施できました。
 (ユーザ定義のシグナル1 :SIGUSR1、ユーザ定義のシグナル2SIGUSR2)

また、スレッドプログラムを組み複数のタイムアウト通知を行う場合
一般的にシグナル通知ではなく、自分自身でタイムアウト検出を行うものでしょうか?(設計次第とも言えそうですが。。)

適していない理由
 1 シグナルは、スレッドごとではなく、プロセスごとに処理される為
 2 シグナルは、ユーザ定義以外のものを使用した場合、
 そのシグナル通知は使用出来ないことになる。
 (例:SIGTERMをタイムアウトで使用した場合、killコマンドの-TERMが無効になる。)



この投稿にコメントする

削除パスワード

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




掲示板提供:Real Integrity