割り込みシステムコールとは何ですか?

割り込みシステムコールとは何ですか?

私は読んでいます。アプエそしてシステムコール割り込みチャプターが私を混乱させます。

本をもとに私が理解した内容を書きたいのですが訂正してください。

  1. 初期のUNIXシステムの特徴は、「遅い」システムコールでプロセスがブロックされている間にシグナルが捕捉されると、システムコールが中断されることです。システムコールはエラーを返し、 errnoに設定されますEINTR。ここでは、シグナルが発生してプロセスがそれをキャッチしたため、ブロックされたシステムコールを起動する必要がある可能性が高いと仮定します。

    だからそれが言うのはより早いUNIXシステムの特徴があります。私のプログラムがシステムコールを使用している場合、プログラムはいつでもシグナルをキャプチャすると中断/停止します。 (デフォルトハンドラはキャプチャと見なされますか?)

    たとえば、10GBのデータを読み取るシステムコールがある場合、読み込み中にシグナル(たとえば)をread送信すると失敗して返されます。kill -SIGUSR1 pidread


  1. アプリケーションが中断されたシステムコールを処理しないようにするために、4.2BSDは中断された特定のシステムコールを自動的に再開する機能を導入しました。自動再起動のためのシステムコールはioctl、、、、、およびです。前述のように、これらの機能の最初の5つは、低速デバイスからの信号によってのみ中断されます。信号がキャッチされると常に中断されます。これにより、中断時に操作を再開したくないアプリケーションに問題が発生する可能性があるため、4.3BSDではプロセスが信号でこの機能を無効にすることができます。readreadvwritewritevwaitwaitpidwaitwaitpid

だから前に自動再起動導入された後、中断されたシステムコールを直接処理する必要がありました。次のコードを書く必要があります。

システムコールを中断する際の問題は、エラーリターンを明示的に処理する必要があることです。一般的なコードシーケンス(読み取り操作を想定し、中断された場合でも読み取りを再開すると仮定)は次のとおりです。

again:
    if ((n = read(fd, buf, BUFFSIZE)) < 0) {
        if (errno == EINTR)
        goto again; /* just an interrupted system call */
        /* handle other errors */
}

しかし、今ではこの種のコードを書く必要はありません。自動再起動器具。


それでは、私の理解がすべて正確であれば、今中断されたシステムコールについて何/なぜ気にする必要がありますか?システム/オペレーティングシステムが自動的に処理するようです。

ベストアンサー1

シグナルハンドラによるシステムコールの中断は、さまざまなブロッキングシステムコールの場合にのみ発生し、プログラマが明示的に設定したシグナルハンドラによってシステムコールが中断された場合に発生します。

さらに、自動システムコールの再起動任意に選択できる特徴。SA_RESTARTシグナルハンドラを構築するときにフラグを付けて、システムコールを自動的に再開することを選択できます。 (例えば)Linuxに規定されているように信号(7)マニュアルページ:

   If  a  signal  handler  is  invoked while a system call or library
   function call is blocked, then either:

   * the call is automatically restarted  after  the  signal  handler
     returns; or

   * the call fails with the error EINTR.

   Which  of  these two behaviors occurs depends on the interface and
   whether or not  the  signal  handler  was  established  using  the
   SA_RESTART  flag (see sigaction(2)). 

上記の引用の最後の文が示すように、この機能を使用することを選択しても、すべてのシステム呼び出しに適用されるわけではなく、適用されるシステム呼び出しのセットはUNIX実装によって異なります。 Linuxsignal(7)のマニュアルページでは、このフラグを使用すると自動的に再起動される複数のシステムコールを指摘していますSA_RESTARTが、次のようなハンドラを構築するときにこのフラグを指定しても再起動しないさまざまなシステムコールも指摘しています。

   * "Input" socket interfaces, when a timeout (SO_RCVTIMEO) has been
     set  on  the  socket  using  setsockopt(2):  accept(2), recv(2),
     recvfrom(2), recvmmsg(2) (also with  a  non-NULL  timeout  argu‐
     ment), and recvmsg(2).

   * "Output"  socket  interfaces,  when  a timeout (SO_RCVTIMEO) has
     been set on the socket using setsockopt(2): connect(2), send(2),
     sendto(2), and sendmsg(2).

   * File   descriptor   multiplexing   interfaces:    epoll_wait(2),
     epoll_pwait(2), poll(2), ppoll(2), select(2), and pselect(2).

   * System  V  IPC  interfaces:  msgrcv(2), msgsnd(2), semop(2), and
     semtimedop(2).

これらのシステムコールでは、APUEで説明されている形式のループを使用して手動で再起動することが重要です。例:

while ((ret = some_syscall(...)) == -1 && errno == EINTR)
    continue;
if (ret == -1)
    /* Handle error */ ;

おすすめ記事