Потоки ядра в posix

#c #c #multithreading #posix #multicore

#c #c #многопоточность #posix #многоядерный

Вопрос:

Насколько я понимаю, ядро имеет потоки ядра для каждого ядра на компьютере, и потоки из пользовательского пространства запланированы на эти потоки ядра (ОС решает, какой поток из приложения подключается к какому потоку ядра). Допустим, я хочу создать приложение, которое использует X количество ядер на компьютере с X ядрами. Если я использую обычные pthreads, я думаю, было бы возможно, что ОС решит, чтобы все потоки, которые я создал, были запланированы на одно ядро. Как я могу гарантировать, что каждый поток один на один с потоками ядра?

Ответ №1:

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

Возможно, вас интересует привязка к процессору с непереносимыми функциями, такими как pthread_attr_setaffinity_np

Комментарии:

1. да, это просто то, о чем я думал. Если кто-то хотел бы иметь как можно больше параллелизма, и он запускает выделенную систему, в которой выполняется этот конкретный процесс, процесс мог бы лучше знать, как разделить потоки пользовательского уровня между потоками уровня ядра, и я думаю, что аффинность — это то, что я хотел бы установить вручную

2. @Silverrocker Имейте в виду, что это часто не так просто. Система / ОС также требует некоторой обработки, например, запущены другие демоны. Или ядро выполняет сетевую обработку, обработку файловой системы и т. Д. Если вы привязали один из своих потоков к ядру, и этот поток заблокирован, например, для ввода-вывода или мьютексов / семафоров, это ядро бездействует, в то время как оно могло запустить другой поток, который каким-то образом был вытеснен из его ядра. ОС в большинстве случаев очень хороша в планировании потоков и процессов для максимального параллелизма.

3. Спасибо! Вы указали на некоторые хорошие вещи, о которых я не думал.

Ответ №2:

Вы немного не понимаете. «потоки ядра» в Linux — это в основном задачи ядра, которые запланированы вместе с другими процессами и потоками. Когда запускается планировщик ядра, алгоритм планирования решает, какой процесс / поток из пула выполняемых потоков будет запланирован для следующего запуска на данном ядре процессора. Как упоминал @Basile Starynkevitch, вы можете указать ядру привязывать отдельные потоки из вашего приложения к определенному ядру, что означает, что планировщик операционной системы рассмотрит возможность запуска его только на этом ядре вместе с другими потоками, которые не привязаны к определенному ядру.

В общем случае при многопоточности вы не хотите, чтобы количество потоков было равно количеству ядер, если только вы не выполняете обработку исключительно с привязкой к процессору, вам нужно количество потоков> количество ядер. При ожидании сетевого или дискового ввода-вывода (т.Е. Когда вы ожидаете в accept(2), recv(2) или read(2)) ваш поток не считается работоспособным. Если N потоков> N ядер, операционная система может запланировать другой ваш поток для выполнения работы в ожидании этого ввода-вывода.

Комментарии:

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

Ответ №3:

То, что вы упомянули, является одной из возможных моделей для реализации потоков. Но такая иерархическая модель может вообще не соответствовать данной реализации потока POSIX. Поскольку кто-то уже упоминал linux, у него его нет, все потоки равны с точки зрения планировщика. Они конкурируют за одни и те же ресурсы, если вы не укажете что-то дополнительное.

Последний раз, когда я видел такую иерархическую модель, был на машине с ОС IRIX, давным-давно.

Итак, в целом, в POSIX нет общего правила для этого, вам нужно будет просмотреть документацию вашей конкретной ОС или задать более конкретный вопрос об этом.