6

のを使用してタイムアウトの間隔を設定しit_intervalたいと思います。 しかし、私の例では、1回しか印刷できません。 どうしたの?間隔を設定するにはどうすればよいですか? newValue
timeout

これは私のコードです:

int main()
{
int efd =epoll_create(256);             
setnonblock(efd);
struct epoll_event ev,events[256];

int tfd;//timer fd

if((tfd= timerfd_create(CLOCK_MONOTONIC,TFD_NONBLOCK)) < 0)
  cout<<"timerfd create error"<<endl;

struct itimerspec newValue;
struct itimerspec oldValue;
bzero(&newValue,sizeof(newValue));  
bzero(&oldValue,sizeof(oldValue));
struct timespec ts;
ts.tv_sec = 5;
ts.tv_nsec = 0;

    //both interval and value have been set
    newValue.it_value = ts; 
    newValue.it_interval = ts;
    if( timerfd_settime(tfd,0,&newValue,&oldValue) <0)
    {
        cout<<"settime error"<<strerror(errno)<<endl;
    }   

    ev.data.fd = tfd;
    ev.events = EPOLLIN | EPOLLET;

    if( epoll_ctl(efd,EPOLL_CTL_ADD,tfd,&ev) < 0)
        cout<<"epoll_ctl error"<<endl;

    int num = 0;
    while(1)
    {
       if((num=epoll_wait(efd,events,256,1000)) > 0)
       {//justice
            for(int i=0;i<num;i++)
            {
                if(events[i].data.fd == tfd)
                {
                    cout<<"timeout"<<endl;
                }
        }       
    }
    }   
return 0;
}
4

1 に答える 1

19

これは、EPOLLETを使用していて、tfdに生成されたデータをread()していないためです。タイマーの有効期限は、読み取る必要のある8バイトのデータを「書き込み」ます。実際に読み取る必要があります。「タイムアウト」を印刷するときにこれを追加します。

uint64_t value;
read(tfd, &value, 8);

詳細:EPOLLETはエッジトリガーを要求します。つまり、epoll_wait()は、データを読み取るまで、ファイル記述子tfdで「データの入力準備ができました」と1回だけ通知します。つまり、そのデータを読み取らなかった限り、epoll_wait()を今後呼び出しても、同じ記述子が再び返されることはありません。この動作は、通常のソケットで役立ちます。たとえば、メインスレッドでepoll_wait()を実行し、一部のデータの準備ができていることを確認してから、別のスレッドを起動して読み取ります。メインスレッドはすぐにepoll_wait()に戻ります。ただし、ファイル記述子からのデータがまだ読み取られていなくても、すぐにウェイクアップすることは望ましくありません。

EPOLLETを使用しない例も、別の方法で間違っていると思います。read()を使用しないため、tfdは最初の遅延後に常に読み取り可能であり、最初の遅延後に可能な限り高速に「タイムアウト」を出力します。有効期限が切れます。

于 2012-09-02T12:44:39.993 に答える