4

スレッドAがあり、スレッドB、C、およびDにシグナルを送信したいとします。このようなことを実行できますか。

SendSignalTo( ThreadB, SIGUSR1 );
SendSignalTo( ThreadC, SIGUSR1 );
SendSignalTo( ThreadD, SIGUSR1 );

SIGUSR1シグナルハンドラーを使用すると、次のように、スレッドB、C、およびDに対して異なる方法で定義されます。

void SIGUSR1_Handler_for_ThreadB(...){...}
void SIGUSR1_Handler_for_ThreadC(...){...}
void SIGUSR1_Handler_for_ThreadD(...){...}

そうでない場合は、代替手段は何ですか。

4

2 に答える 2

5

を使用して特定のスレッドにシグナルを送信できますpthread_kill()。または、GNU 固有であることを気にしない場合は、pthread_sigqueue()(1 つを指定するintvoid *、ハンドラーが を介してアクセスできますinfo->si_value) を使用して、シグナルを送信できます。

プロセスのシグナルごとに 1 つのシグナル ハンドラーしかありません。これは、特定のシグナルが、たまたまどのスレッドであっても、常に同じハンドラー関数を呼び出すことを意味します。1 つのスレッドが新しいシグナル ハンドラを設定すると、すべてのスレッドのシグナル ハンドラが変更されます。

ただし、回避策は簡単です。スレッドごとの関数ポインターを使用して、シグナル ハンドラーが呼び出す関数を定義します。シグナル ハンドラーの制限を覚えておいてください。シグナル ハンドラーでは非同期シグナル セーフ関数のみを使用できます。

/* Simplify by defining the signal handler function type, assume SA_SIGINFO */
typedef void (*signal_handler_t)(int, siginfo_t *, void *);

/* Per-thread variable pointing to the desired function */
static __thread signal_handler_t  thread_handler = NULL;

/* Process-wide actual signal handler */
static void signal_handler(int signum, siginfo_t *info, void *context)
{
    signal_handler_t  func;

    func = __sync_fetch_and_or(&thread_handler, (signal_handler_t)0);

    if (func)
            func(signum, info, context);
}

アトミック ロード ( __sync_fetch_and_or()) を使用すると、単純なアトミック ストアを使用して、シグナルをブロックすることなく、いつでもスレッドごとのハンドラーを簡単に変更できます。機能への切り替えnew_thread_handlerはその後です

    signal_handler_t  func;

    do {
        func = thread_handler;
    } while (!__sync_bool_compare_and_swap(&thread_handler, func, new_thread_handler));

関数スイッチと関数スイッチは両方とも 1 つの__sync_fetch_and_or()C++11 スタイルの__atomic_呼び出しで置き換えることができますが、最近の GCC がまだ十分にないので、古いスタイルの__sync_呼び出しをまだ使用しています。

POSIX は、リアルタイムシグナル 、SIGRTMIN+0SIGRTMIN+1..、もサポートしていますSIGRTMAX。それらには、複数のそれらを同時に保留できるという追加の利点があります。それらは、従来の信号よりもこの種のものにはるかに適しています.

于 2012-10-10T16:15:11.537 に答える
4

はいといいえ。

私にとって新しいのは、同じプロセスの下のスレッドにシグナルを送信できる pthread_kill() 関数です。

http://linux.die.net/man/3/pthread_kill

ページ下部の注意事項を必ずお読みください...

シグナルの処理はプロセス全体に適用されます。シグナル ハンドラがインストールされている場合、ハンドラはスレッド スレッドで呼び出されますが、シグナルの処理が「停止」、「続行」、または「終了」の場合、このアクションはプロセスに影響します。全体のプロセス。

これをどのように解釈するかというと、プロセスのハンドラーが呼び出され、その条件を満たしている限り、ハンドラーがそのスレッドに対してのみ呼び出されたことを認識して適切なアクションを実行できます。

于 2012-10-10T13:44:36.633 に答える