2017-02-02 56 views
-1

複数のスレッドがメソッドを呼び出し、timer_createと timer_settimeでタイマーを設定します。私は、ハンドラが呼び出されたとき= &info;C++の複数のスレッドのtimer_create

しかし、それは別のスレッドID(おそらく、主な機能のid)が付属していますし、私の

sev.sigev_value.sival_ptrにスレッドIDを渡すためにしようとしていますキャンセルメソッドは呼び出されません。

 timer_t timerid; 
     struct sigevent sev; 
     struct itimerspec its; 
     long long freq_nanosecs; 
     sigset_t mask; 
     struct sigaction sa; 

     sa.sa_flags = SA_SIGINFO; 
     sa.sa_sigaction = &handler; 
     sigemptyset(&sa.sa_mask); 
     sigaction(SIGUSR1, &sa, NULL); 

     sev.sigev_notify = SIGEV_SIGNAL; 
     sev.sigev_signo = SIGUSR1; 
     sev.sigev_value.sival_ptr = &info; 
     timer_create(CLOCK_REALTIME, &sev, &timerid); 
     /* Start the timer */ 

     its.it_value.tv_sec = 3; 
     its.it_value.tv_nsec = 0; 
     its.it_interval.tv_sec = its.it_value.tv_sec; 
     its.it_interval.tv_nsec = its.it_value.tv_nsec; 

     timer_settime(timerid, 0, &its, NULL); 

今ハンドラは、私の問題は、私は正しく、呼び出し元のスレッドから来ている一意の値に基づいて、キャンセルメソッドを呼び出すために識別するための適切な方法を識別することができないということです

 Info *inc; 
     inc = (Info *)si->si_value.sival_ptr; 

     std::thread::id thread_id = std::this_thread::get_id(); 

     if(inc->thread_id != thread_id){ 
       LOG << "This thread is not blocking"; 
     } else { 
       printf("Caught signal %d from timer\n", sig); 

       cancel(...); 
     } 

です。

任意提案

+1

「SIGEV_SIGNAL」(シグナルをプロセスに送信する)ではなく、 'SIGEV_THREAD_ID'(特定のスレッドでシグナルをターゲットにする)を使用しているのでしょうか? – Hasturkun

+0

これがシグナルハンドラのコードであれば、そこで呼び出される関数は非同期シグナルセーフではありません。つまり、未定義の動作です。 –

+0

@ MaximEgorushkinこれはシグナルハンドラのコードです。非同期シグナルを安全にするためにはどうすればよいですか? – cateof

答えて

1

信号によって中断及びNO SA_RESTARTは、その信号のために使用されていない場合connect又はread/recv/recvmsg/recvfromリターンEINTRを遮断します。これはalarmシステムコールの主な目的ですが、マルチスレッド化の前に発明されたので、特定のスレッドではなくプロセスに信号を送信します。

ブロッキングソケットから切断するにはconnectSIGEV_THREAD_IDを使用して特定のスレッドに信号を送信するタイマーを呼び出します。信号ハンドラを SIG_IGNに送信し、SA_RESTARTがその信号に使用されていないことを確認してください。

+0

私はソケットを操作することができません、私のコードはそこにアクセスできません。 – cateof

+0

しかし、私は、タイマが経過すると、私はキャンセル(connection_ptr) – cateof

+0

@cateofのようなものを呼び出すことができる接続ポインタを持っています。私はそのスレッドに 'connect'でブロックされたシグナルを送信しようとします。 'strace'の下で実行します。 –

関連する問題