デフォルトでは、ユーザー信号SIGUSR1とSIGUSR2はプロセスまたはスレッドを終了します。ハンドラを設定するにはどうすればよいですか?このトピックに関するさまざまな記事を読んでみましたが、このトピックに初めて触れたため、必要に応じて移行することは不可能でした。
要件は次のとおりです。ループ内で一連のコマンドを実行する多くのプロデューサースレッド(pthread)があり、各反復の終わりにプライマリコンシューマスレッドでシグワットSIGURS1を待ち、次のスレッドにのみ移動します。信号を受信してから繰り返します。ただし、基本的に実行されるので完了です。
それら。ここでは、次の反復に切り替えるためにこれらの信号を受信すると、処理は完了する。
答え1
シグナルハンドラを設定するために使用できる多くのAPIがあります。そのうちの1つの例を見てみましょう。
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
static void signal_handler(int signo)
{
# define signal_message "Signal received\n"
write(1, signal_message, strlen(signal_message));
# undef signal_message
}
int main(void)
{
struct sigaction new_handler = {
.sa_handler = signal_handler,
};
if (sigaction(SIGUSR1, &new_handler, NULL) < 0) {
perror("sigaction");
}
pause();
return 0;
}
このsigaction()
関数は新しいシグナルハンドラをインストールし、その署名は次のとおりです。
int sigaction(int signum,
const struct sigaction *act,
struct sigaction *oldact);
最初のパラメータはシグナル番号です(たとえば、SIGUSR1
2番目のパラメータはハンドラの詳細を含む構造体へのポインタ、3番目のパラメータはハンドラstruct sigaction
がstruct sigaction
保存される前の値へのポインタです。)NULL
同じ前の値は気にしないでください。
フィールドの1つstruct sigaction
はsa_handler
信号処理機能へのポインタです。関数の署名は次のようにする必要があります。
void function_name(int signo);
この関数は、void
受信した信号番号をパラメータとして返し、受け入れます。
要約すると、例ではシグナルハンドラをインストールしSIGUSR
てからを呼び出して、pause()
シグナルが受信されるまで実行を停止します。その後、SIGUSR
このコードを実行しているプロセスに信号を渡すと、Signal received
標準出力として印刷されます。