0

シグナルハンドラー関数のaddsignal()関数について読んだところ、デフォルトの動作が上書きされる可能性があります。

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void signalHandler();
int main(void) {
    signal(SIGUSR1, signalHandler);
    sleep(60);
    printf("I wake up");
    return 0;
}
void signalHandler() {
    signal(SIGUSR1, signalHandler);// I add this line to overwrite the default behaviour 
    printf("I received the signal");
}

そして、私は別のプロセスでそれをトリガーします

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {

    kill(5061, SIGUSR1); // 5061 is the receiver pid, kill(argv[1], SIGUSR1) doesn't working, when I get 5061 as parameter
    puts("send the signal ");
    return 0;
}

wake up受信機は、信号を受信するとすぐに処理しSIGUSR1ます。sleep他のプロセスからの信号を受信した場合でも、受信機を継続させるにはどうすればよいですか?

ところで、 5061をパラメーターとして取得したときにkill(5061, SIGUSR1);、5061がレシーバーpidであるのに、kill(argv[1], SIGUSR1)機能しないのはなぜですか?

4

3 に答える 3

5

sleep(3)マニュアルページから:

戻り値

要求された時間が経過した場合はゼロ、または呼び出しがシグナルハンドラーによって中断された場合は、スリープするまでの秒数。

したがって、単に呼び出す代わりにsleep、戻り値を確認してループで呼び出す必要があります。

int sleep_time = 60;
while ((sleep_time = sleep(sleep_time)) > 0)
    ;
于 2012-10-28T07:54:44.747 に答える
3

あなたの質問 (なぜkill(argv[1], SIGUSR1)うまくいかないのか) は、実際には信号に関係していませんが、基本的な C プログラミングに関係しています。Linux で (すべての警告とデバッグ情報を含めて)コンパイルし、gcc -Wall -g警告が表示されなくなるまでコードを改善してください。

kill(2)の man ページを注意深く読んでください (Linux では、 Ubuntu または Debian にmanpagesandmanpages-devなどのパッケージをインストールした後、入力してコンピュータで読むことができます)。signal(2)およびsignal(7)の man ページも注意深く読んでください。これらのマニュアルページを数回読んでください。man-dbman 2 kill

次に、kill syscall が次のように宣言されていることを理解します。

int kill(pid_t pid, int sig);

は整数型であるため、 (文字列、つまり a ) を整数pid_tに変換する必要があります(また、 は整数ではなく文字列であるため、エラーなしでコンパイルすることさえできません)。だから使用してください:argv[1]char*kill(argv[1], SIGUSR1)argv[1]

kill((pid_t) atoi(argv[1]), SIGUSR1);

man ページには、 を使用signal(SIGUSR1, SIG_DFL)してデフォルトの動作を復元し、signal(SIGUSR1, SIG_IGN)そのシグナルを無視する必要があることも記載されています。

もちろん、のマニュアル ページで説明されているように、sigaction(2)signal(2)を使用することをお勧めします。

最後に、man ページを読む習慣を身につけ、 Advanced Linux ProgrammingAdvanced Unix Programmingなどの優れた本を何時間も読んでください。彼らは、私たちが数分で説明できるよりもはるかにうまく説明しています。C プログラミングに慣れていない場合は、 C プログラミングに関する優れた本も読んでください。

于 2012-10-28T07:52:20.660 に答える
2

以前に試したことはありませんが、代わりにsigaction(2)SA_RESTARTを使用してフラグを設定できます。これにより、システムコールが再起動可能になります。

編集:実際にはこれは機能しません。signal (7)のマニュアル ページによると、すべてのシステム コールが再起動できるわけではありません。

sleep(3) 関数も、ハンドラーによって中断された場合、再開されることはありませんが、成功を返します: sleep までの残りの秒数

sleepそのため、代わりに残り時間を使用して関数を再度呼び出す必要があります。

于 2012-10-28T07:50:58.447 に答える