Linux C++: функция обратного вызова libaio никогда не вызывается?

Я на Ubuntu 16.10 с g++ 6.2, тестирую функцию libaio:

1. I was trying to test io_set_callback() function
2. I was using main thread and a child thread to talk by a pipe
3. child thread writes periodically (by alarm timer, signal), and main thread reads

Я надеюсь использовать функцию "обратного вызова" для получения уведомлений. Это не сработало, как ожидалось: функция обратного вызова "read_done" никогда не вызывается

Мои вопросы:

1. I expected my program should call "read_done" function, but actually not.
2. Why the output prints 2 "Enter while" each time? 
I hope it only print together with "thread write msg:..."
3. I tried to comment out "io_getevents" line, same result.

Я не уверен, что в режиме обратного вызова все еще нужен io_getevents? Так как исправить мою программу, чтобы она работала так, как я ожидал? Благодарю.

1 ответ

Решение

Вам необходимо интегрировать io_queue_run(3) а также io_queue_init(3) в вашу программу. Хотя это не новые функции, они, похоже, не находятся в руководствах для множества дистрибутивов, которые в настоящее время поставляются. Вот пара руководств:

http://manpages.ubuntu.com/manpages/precise/en/man3/io_queue_run.3.html http://manpages.ubuntu.com/manpages/precise/en/man3/io_queue_init.3.html

И, конечно же, руководства на самом деле не говорят этого, но io_queue_run это то, что вызывает обратные вызовы, которые вы установили в io_set_callback,

ОБНОВЛЕНО: Тьфу. Вот источник для io_queue_run из libaio-0.3.109 для Centos / RHEL (лицензия LGPL, 2002 г., Red Hat, Inc.)

int io_queue_run(io_context_t ctx)
{
    static struct timespec timeout = { 0, 0 };
    struct io_event event;
    int ret;

    /* FIXME: batch requests? */
    while (1 == (ret = io_getevents(ctx, 0, 1, &event, &timeout))) {
        io_callback_t cb = (io_callback_t)event.data;
        struct iocb *iocb = event.obj;

        cb(ctx, iocb, event.res, event.res2);
    }

    return ret;
}

Вы бы никогда не хотели называть это без io_queue_wait вызов. И, io_queue_wait Вызов закомментирован в заголовке, который включен в Centos/RHEL 6 и 7. Я не думаю, что вам следует вызывать эту функцию.

Вместо этого я думаю, что вы должны включить этот источник в свой собственный код, а затем изменить его, чтобы сделать то, что вы хотите. Вы можете добавить к этому аргументу тайм-аут io_queue_run и просто замените его на io_getevents, вместо того, чтобы беспокоиться о io_queue_wait, Здесь даже есть патч, который делает io_queue_run НАМНОГО лучше: https://lwn.net/Articles/39285/).

Другие вопросы по тегам