Я на 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? Так как исправить мою программу, чтобы она работала так, как я ожидал? Благодарю.
Вам необходимо интегрировать 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, Copyright 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/).
Других решений пока нет …