2017-06-20 1 views
0

私はアプリケーションからboostを削除しています(pre C++ 11を使用しているためにboostを取り除きたいからです)。そして同じものの一部として次の問題を実行しました。SIGINFOのSIGINFO構造体のsockfd

私は、ブースト(async_connect、async_writeおよびasync_read呼び出し)を使用して、リモートサーバーからデータを非同期に接続し、要求し、受信するコードを用意しています。私は非同期モードで動作するlinuxネイティブソケットと同じものを置き換える予定です。

私は見て始めました ioctl(_sockfd、FIOASYNC、&); ソケットを非同期モードに設定します。 次も設定します fcntl(_sockfd、F_SETOWN、getpid()); ソケットを作成するプロセスに向けられたすべてのsockfd関連シグナルを取得します。 SIGIO信号を処理すると、さまざまな信号関連情報を含むsiginfo_t構造体にアクセスできます。

しかし、受信したsiginfo構造体インスタンスからsockfdを取得することができません。これにより、sockfd; sigioシグナルが捕捉されにくくなります。 si-> si_fdは、connectが呼び出された_sockfdと一致しません。 SIGIOのSIGINFOのfdが、この信号が生成されたsockfdと一致しないのはなぜですか。 siginfoの内容も信頼できますか? socket(7) manページから

+2

シグナルAPIを無視し、select()やpoll()を使ってソケット処理を実装することをお勧めします。シグナルはマルチスレッドやオブジェクト指向設計ではうまく動作せず、非同期ソケットが必要で、 C++には両方が必要になる大きなチャンスがあります。 – gabry

+0

sigaction()を使ってシグナルハンドラを確立するときに 'SA_SIGINFO'を設定しましたか?下記も参照してくださいhttps://stackoverflow.com/questions/19866754/sigio-arriving-for-file-descriptors-i-did-not-set-it-for-and-when-no-io-is-possi – nos

答えて

0

Signals 
    ...[SIGPIPE para elided]... 

    When requested with the FIOSETOWN fcntl(2) or SIOCSPGRP ioctl(2), 
    SIGIO is sent when an I/O event occurs. It is possible to use 
    poll(2) or select(2) in the signal handler to find out which socket 
    the event occurred on. An alternative (in Linux 2.2) is to set a 
    real-time signal using the F_SETSIG fcntl(2); the handler of the real 
    time signal will be called with the file descriptor in the si_fd 
    field of its siginfo_t. See fcntl(2) for more information. 

    Under some circumstances (e.g., multiple processes accessing a single 
    socket), the condition that caused the SIGIO may have already 
    disappeared when the process reacts to the signal. If this happens, 
    the process should wait again because Linux will resend the signal 
    later. 

ので、

  • いずれかfcntl(sockfd, F_SETSIG, ...)に代わりリアルタイム信号を使用し、
  • または使用にpollselectを非ブロックトリガするfdを特定するシグナルハンドラ、(select/poll)を使用してください。これはもっと普通のIMEですが、厄介な信号処理の問題を回避しますが、イベントループの周りにプログラム全体を再構築する必要があるかもしれません。...
0

POSIX aioはどうですか?私は個人的にそれを使用することはなかったが、おそらくそれはあなたが探しているものです。 https://linux.die.net/man/7/aio

なぜ、あなたはboost::asioが好きではありませんか? boost::thread,boost::regexpなど、実際にはC++ 11/14では冗長なものもありますが、boost::filesystemはC++では冗長です17。しかし、標準ライブラリにはasioアナログが含まれていません。 IMHO、あなたは一から自分自身を書くよりも、準備ができて、テストされ、移植性があり、広く普及したソリューションを使用する方が良いでしょう。

+0

ブースト:私のユースケースでは、asioは事実上重いです。ブーストIOServiceのキューはあまりにも一般的で、オーバーヘッドがあります(相互にロックを解除し、すべてのpoll_oneでロックします)。したがって、私はそれを取り除くことを考えています。 – user2496905

関連する問題