Поток может быть предвосхищен посреди системного вызова ядра?

Я работаю, 2 потока (предположите, что они - pthreads в настоящий момент). Thread_1 () делает пользовательский вызов API, который в конечном счете делает некоторую работу в ядре. Thread_2 () находится полностью в пространстве пользователя.

Мой вопрос: Может Thread_2 () начинают выполняться путем предвосхищения Thread_1 (), в то время как вызов API происходит, управление где-нибудь в ядре? В противном случае, почему, и если я хочу, чтобы этот сценарий произошел (по каким-либо причинам), что я должен сделать?

7
задан TCSGrad 12 December 2009 в 02:57
поделиться

3 ответа

If you are asking whether a blocking kernel call like an fread() which requires disk IO can be pre-empted, then yes.

More specifically a blocking call will basically put Thread_1 to sleep while waiting for whatever it's waiting for. If Thread_1 is asleep then Thread_2 will be scheduled to run (unless there's something of higher priority waiting to run).

Edit: If you want a way to be "fairly confident" that Thread_1 is performing a blocking call, make Thread_2 lower priority than Thread_1 (so that it generally doesn't run unless Thread_1 is blocked) and when it runs, it elevates its priority to a higher level than Thread_1 until the hardware interrupt has been delivered, at which point it lowers its priority and calls sched_yield().

5
ответ дан 6 December 2019 в 09:20
поделиться

Calls to the kernel are considered to be either blocking or nonblocking. A blocking call (such as waiting for data to read from a network socket) can certainly be preempted with no action required on your part. Other threads will continue to run. Nonblocking kernel calls can be considered to be very fast and in practical terms it won't matter if you can actually preempt them or not.

Generally, when writing multithreaded code, you concentrate on how those threads interact with each other, and leave their interaction with the kernel up to the kernel to manage. It's designed to do a pretty good job.

8
ответ дан 6 December 2019 в 09:20
поделиться

Это зависит от ядра. Классически ядра не допускали вытеснения (за исключением определенных моментов, когда поток засыпал). Но в более новых ядрах есть возможность включения вытеснения внутри самого ядра.

Linux поддерживает вытесняемое ядро, если оно построено с использованием CONFIG_PREEMPT. Из документации ядра:

Эта опция уменьшает задержку ядра, делая весь код ядра (который не выполняется в критическом разделе) вытесняемый. Это позволяет реагировать на интерактивные события позволяет принудительно прервать процесс с низким приоритетом даже если он находится в режиме ядра при выполнении системного вызова и будет в противном случае вы не можете достичь естественной точки упреждения. Это позволяет приложениям работать более плавно, даже если система находится под нагрузкой за счет немного меньшей пропускной способности и небольшие накладные расходы времени выполнения для кода ядра.

Выберите это, если вы собираете ядро ​​для настольного компьютера или встроенная система с требованиями к задержке в миллисекундах range.

7
ответ дан 6 December 2019 в 09:20
поделиться