2

私はマルチスレッドプログラムを持っています。メイン スレッドは getchar を使用して、他のすべてのスレッドとそれ自体を閉じます。子スレッドの 1 つで使用されるタイマー機能があります。このスレッドは、タイマーの有効期限に SIG34 を使用します。

ある時点で、私は以下のように受け取りSIG34ます。これは、メイン スレッドの getchar に影響を与えており、プログラムが異常終了します。同じことを理解するのを手伝ってください。

Program received signal SIG34, Real-time event 34.
0x00007ffff6ea38cd in read () from /lib/x86_64-linux-gnu/libc.so.6

(gdb) bt
#0  0x00007ffff6ea38cd in read () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007ffff6e37ff8 in _IO_file_underflow () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x00007ffff6e3903e in _IO_default_uflow () from /lib/x86_64-linux-gnu/libc.so.6
#3  0x00007ffff6e2fb28 in getchar () from /lib/x86_64-linux-gnu/libc.so.6
#4  0x0000000000401eef in main (argc=1, argv=0x7fffffffe178) at ../../src/SimMain.c:186

ノート:

子スレッドでは、タイマー シグナリング用に SIGRTMIN (システムでは SIG34 に変換) を割り当て、ハンドラーも用意しています。このハンドラーはグローバル変数を設定して、コース ポスト タイマーの有効期限を変更できるようにします。しかし、getchar が問題になっている理由は不明です。

タイマーの初期化と使用法:

/* Timer macros */
     #define CLOCKID CLOCK_REALTIME
     #define SIGRT_OFFSET 4 // was 0 before, hence, SIG34, now it is SIG38

     #define SIG (SIGRTMIN + SIGRT_OFFSET)

    void cc_timer_init() 
{
    // Install the timer handler...

    struct sigevent sev;
    long long freq_nanosecs;
    struct sigaction disc_action;

    /* Establish timer_handler for timer signal */


    memset (&disc_action, 0, sizeof (disc_action));
    disc_action.sa_flags = SA_SIGINFO; //0 before
    disc_action.sa_sigaction = disc_timer_handler;
    sigaction(SIG, &disc_action, NULL);
    myState = INIT_STATE;


    /* Create the timer */

    sev.sigev_notify = SIGEV_SIGNAL;
    sev.sigev_signo = SIG;
    sev.sigev_value.sival_ptr = &timerid;
    timer_create(CLOCKID, &sev, &timerid);


    /* Set itimerspec to start the timer */

    freq_nanosecs = TMR_TV_NSEC;
    v_itimerspec.it_value.tv_sec = TMR_TV_SEC;
    v_itimerspec.it_value.tv_nsec = freq_nanosecs % 1000000000;
    v_itimerspec.it_interval.tv_sec = 0;
    v_itimerspec.it_interval.tv_nsec = 0;

}

static void disc_timer_handler(int sig, siginfo_t *si, void *uc)
{
    /* Global variable that I set */
    State = MID_1_STATE;
}

/* In another part...*/
.
.
.
case INIT_STATE :
    {
        v_itimerspec.it_value.tv_sec = TMR_TV_SEC;
        timer_settime(timerid, 0, &v_itimerspec, NULL);
        ret_val = SUCCESS;
    }
    break;
    .
    .
    .
4

1 に答える 1

3

ubuntu pthreads 情報シート (LinuxThreads) から:

      In addition to the main (initial) thread, and the threads  that  the
      program  creates using pthread_create(3), the implementation creates
      a  "manager"  thread.   This  thread  handles  thread  creation  and
      termination.   (Problems  can result if this thread is inadvertently
      killed.)

   -  Signals are used internally by the implementation.  On Linux 2.2 and
      later,  the  first three real-time signals are used.

他の実装では、最初の 2 つの RT 信号を使用します。スレッド管理で使用されるこれら 2 つまたは 3 つのシグナルの上に SIGRTMIN を設定します。pthreads(7) の man ページに SIGRTMIN について記載されている内容を参照してください。そしてそれに応じて調整します。

于 2013-09-25T12:52:20.463 に答える