2

Libevent の使い方を学んでいます。保留とアクティブの違いがわかりません。私の意見では、event_base にイベントが追加され、イベントが発生していない場合、保留状態になります。呼び出し側が待ち受けているイベントが起きて、それでアクティブな状態になっているのですが、 の説明を読むとevent_pending、コードが吹き飛ばされているのを見て、イベントが保留されているときに、の内部状態を変更するのは悪いと書かれていますそれ、ここでの「保留中」という言葉は誤解だと思いますが、「event_active」のはずです....私は間違っていますか?

#include <event2/event.h>
#include <stdio.h>

/* Change the callback and callback_arg of 'ev', which must not be
 * pending. */
int replace_callback(struct event *ev, event_callback_fn new_callback,
    void *new_callback_arg)
{
    struct event_base *base;
    evutil_socket_t fd;
    short events;

    int pending;

    pending = event_pending(ev, EV_READ|EV_WRITE|EV_SIGNAL|EV_TIMEOUT,
                        NULL);
    if (pending) {
        /* We want to catch this here so that we do not re-assign a
         * pending event.  That would be very very bad. */
        fprintf(stderr,
            "Error! replace_callback called on a pending event!\n");
        return -1;
    }

    event_get_assignment(ev, &base, &fd, &events,
                     NULL /* ignore old callback */ ,
                     NULL /* ignore old callback argument */);

    event_assign(ev, base, fd, events, new_callback, new_callback_arg);
    return 0;
 }
4

2 に答える 2

3

保留中のイベントとは、何らかのアクションがトリガーされ、イベント コールバックの実行が event_base でキューに入れられていることを意味します。

アクティブなイベントは、イベント コールバックが現在実行されている現在のスレッドまたは他のスレッドを意味します (イベント ループを実行していない他のスレッドからイベントを操作できることを忘れないでください)。

保留中のイベントの再割り当ては、スレッド セーフな操作ではありません。event.c で確認できます。

シングル スレッド アプリケーションを作成している場合は、いつでもイベントを再割り当てしても安全だと思います。

于 2012-09-12T18:51:40.237 に答える
2

libevent ブック引用 ( http://www.wangafu.net/~nickm/libevent-book/Ref4_event.html ):

Libevent 関数を呼び出してイベントをセットアップし、それをイベント ベースに関連付けると、イベントは初期化されます。この時点で、追加できます。これにより、ベースで保留中になります。イベントが保留中の場合、イベントをトリガーする条件が発生すると (たとえば、ファイル記述子の状態が変化するか、タイムアウトが期限切れになる)、イベントがアクティブになり、その (ユーザー提供の) コールバック関数が実行されます。

したがって、libevent 用語での「保留中」は、「リアクターに追加されたばかり」を意味します。保留中のイベントを取得するアクション トリガーは必要ありません。簡単なプログラムでこの動作を確認しました:

#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <event.h>

void read_cb( int sock, short which, void *arg )
{
    printf( "read_cb() called\n" );
    fflush( stdout );
    // while our callback is running event is active
}

int main()
{
    struct event_base *base = event_base_new();

    int fd[ 2 ];
    assert( pipe( fd ) == 0 );

    struct event ev;
    event_set( & ev, fd[ 0 ], EV_READ | EV_PERSIST, read_cb, NULL );
    event_base_set( base, & ev );

    assert( event_add( & ev, NULL ) != -1 );
    // it's pending now, just after adding

    printf( "event_pending( ... ) == %d\n", event_pending( & ev, EV_READ, NULL ) );
    fflush( stdout );

    event_base_loop( base, EVLOOP_ONCE );

    return 0;
}

出力:

event_pending( ... ) == 2

于 2014-11-27T16:45:28.180 に答える