Могу ли я предотвратить сдвиг пользовательского пространства Linux в критический код? - PullRequest
5 голосов
/ 19 мая 2010

Я работаю над приложением пользовательского пространства для встроенного проекта Linux, использующего ядро ​​2.6.24.3. Мое приложение передает данные между двумя файловыми узлами, создавая 2 pthread, каждый из которых находится в спящем режиме, до тех пор, пока не завершится асинхронная операция ввода-вывода, после чего оно запускается и запускает обработчик завершения.

Обработчики завершения должны отслеживать количество ожидающих передач и поддерживать несколько связанных списков, которые один поток добавит, а другой удалит.

// sleep here until events arrive or time out expires
for(;;) {
    no_of_events = io_getevents(ctx, 1, num_events, events, &timeout);
    // Process each aio event that has completed or thrown an error
    for (i=0; i<no_of_events; i++) {
        // Get pointer to completion handler
        io_complete = (io_callback_t) events[i].data;
        // Get pointer to data object
        iocb = (struct iocb *) events[i].obj;
        // Call completion handler and pass it the data object
        io_complete(ctx, iocb, events[i].res, events[i].res2);
    }
}

Мой вопрос такой ...

Есть ли простой способ предотвратить выход текущего активного потока, пока он запускает обработчик завершения, а не идет по маршруту блокировки мьютекса / вращения?

Или не удается настроить Linux для предотвращения выдачи pthread при удержании блокировки мьютекса / вращения?

Ответы [ 3 ]

4 голосов
/ 19 мая 2010

Вы можете использовать системный вызов sched_setscheduler(), чтобы временно установить политику планирования потока на SCHED_FIFO, а затем снова установить ее. Со справочной страницы sched_setscheduler():

Процесс SCHED_FIFO выполняется до тех пор, пока он заблокирован запросом ввода / вывода, вытеснено более высоким приоритетом процесс, или он вызывает sched_yield(2).

(В данном контексте «процесс» фактически означает «поток»).

Однако это довольно подозрительное требование. Какую проблему вы хотите решить? Если вы просто пытаетесь защитить свой связанный список обработчиков завершения от одновременного доступа, тогда обычный мьютекс - это путь. Пусть поток завершения заблокирует мьютекс, удалит элемент списка, разблокирует мьютекс и вызовет обработчик завершения.

1 голос
/ 19 мая 2010

Полагаю, вы пытаетесь перехитрить планировщик Linux здесь по неправильным причинам.

Правильное решение - использовать мьютекс для предотвращения параллельной работы обработчиков завершения. Пусть планировщик сделает свою работу.

1 голос
/ 19 мая 2010

Я думаю, что вы захотите использовать мьютексы / блокировки, чтобы предотвратить условия гонки здесь. Мьютексы ни в коем случае не волшебство вуду и могут даже сделать ваш код проще, чем использование произвольных специфических для системы функций, которые вам, возможно, придется перенести через системы. Не знаю, является ли последнее для вас проблемой.

...