3

私はそのようなCコードを持っています

int childid;
int parentid;
void siginthandler(int param)
{
 // if this is the parent process
 if(getpid() == parentid){
   //handler code which sends SIGINT signal to child process
 kill(childid, SIGINT);
 }
 else // if this is the child process
 exit(0);
}

int main()
{
parentid = getpid(); // store parent id in variable parentid, for the parent as well as child process
int pid = fork();
int breakpid;
if(pid != 0){
childid = pid;
breakpid =  wait();
printf("pid = %d\n", breakpid);
}
else
sleep(1000);
}

このコードを実行すると、子プロセスがスリープしている間、親プロセスは待機します。ctrlここで ( +を押して) 親プログラムを中断するcと、UNIX (POSIX 標準) のドキュメントによると、wait 関数は -1 を返し、errno を EINTR に設定する必要があります。ただし、親プロセスが SIGINT シグナルを子プロセスに送信するため、私のコード実装は子プロセスを強制終了します。しかし、驚くべきことに、(親プロセスでは) wait は pid = -1 を返さず、errno は EINTR に設定されます。代わりに、強制終了された子プロセスの ID を返します。

これについての説明はありますか?

4

1 に答える 1

2

でシグナル ハンドラをインストールするとsignal()、次の 2 つのうちのいずれかが発生します。

  1. ほとんどのシステム コールは、シグナルが発生すると中断され、errno に EINTR を設定します。
  2. ほとんどのシステム コールは、シグナルが発生すると自動的に再開されます (そのため、失敗して errno が EINTR に設定されることはありません)。

これら 2 つのどちらがプラットフォームに依存するかは、あなたのプラットフォームに依存します2(おそらく、シグナル ハンドラーをインストールするコードは表示されません)。

代わりにsigaction ()を使用してシグナル ハンドラーをインストールすると、フラグを使用して1またはの動作を制御できます。2SA_RESTART

于 2014-01-30T20:35:46.290 に答える