#c #posix #aio
Вопрос:
Я отправляю 100 запросов, используя aio_write. Я установил sigval (аргумент обратного вызова) для некоторого адреса с помощью request.aio_sigevent.sigev_value.sival_ptr = some_address;
. У каждого запроса свой адрес. Обратный вызов должен записать некоторые данные по адресу.
Я ожидаю, что обратный вызов будет вызван 100 раз со 100 различными аргументами, которые я ему привел. Вместо этого обратный вызов вызывается 100 раз с одним и тем же аргументом каждый раз: аргументом для 100-го запроса. Я пробовал и с SIGEV_THREAD, и с SIGEV_SIGNAL с одинаковым результатом оба раза.
Фрагмент кода, в котором я отправляю запросы:
for (int i = 0; i < num_requests; i ) {
struct aiocb request = build_request(/* snip */, amp;array[i]);
aio_write(amp;request);
}
(где build_request
просто создает a struct aiocb
и записывает в поля aio, а также в aio_sigevent
поля: sigev_notify
, sigev_signo
или sigev_notify_function
, sigev_value.sival_ptr
и.)
Почему это происходит?
Комментарии:
1. Из руководства aio_write : » Блок управления не должен изменяться во время выполнения операции записи».. В вашем случае переменная выходит за пределы области действия, как только заканчивается каждая итерация цикла. Таким образом, это неопределенное поведение как с точки зрения чистого языка Си, так и с точки зрения вызываемого API. Одним из решений является создание статического или динамического массива
aiocb
.2. @kaylum Тьфу, этого бы хватило. Можете ли вы опубликовать это в качестве ответа? Это урок для меня, чтобы в следующий раз прочитать всю справочную страницу целиком… если бы только существовала технология для применения инвариантов, подобных этому 🙂
3. » если бы только существовала технология, позволяющая применять такие инварианты «. Это был бы язык ржавчины 🙂
4. Без сомнения! О, как бы я хотел им воспользоваться 🙂
Ответ №1:
Из руководства aio_write:
Блок управления не должен изменяться во время выполнения операции записи.
В вашем случае переменная выходит за пределы области действия, как только заканчивается каждая итерация цикла. Таким образом, это неопределенное поведение как с точки зрения чистого языка Си, так и с точки зрения вызываемого API. Одним из решений является создание статического или динамического массива aiocb.