|
|
  |
POSIX pthread_* в Linux, когда появилось и как реализовано? |
|
|
|
Jan 21 2007, 14:25
|

Гуру
     
Группа: Админы
Сообщений: 3 621
Регистрация: 18-10-04
Из: Москва
Пользователь №: 904

|
Цитата(InvisibleFed @ Jan 21 2007, 14:07)  Я про 2.4. О тредах знает ТОЛЬКО процесс. Ядро о них ничего не знает. И шедулит оно только процессы. Все остальное - на уровне библиотеки. Процесс как таковой даже тела почти не имеет (я имею ввиду каких-то описательных структур). Если у ядра есть таблица процессов, то таблицы потоков у него нет. В 2.6, может, по другому (хотя я, если честно, в этом сомневаюсь). Не сомневайтесь, а лучше посмотрите исходники библиотек и ядра, а еще почитайте книжку, ссылку на которую я приводил ранее в этой теме. Кроме того, для осознания сути потоков в ядрах 2.4 и 2.6 советую почитать: http://linuxdevices.com/articles/AT6753699732.htmlи http://www-128.ibm.com/developerworks/linu...-threading.html
--------------------
BR, Makc В недуге рождены, вскормлены тленом, подлежим распаду. (с) У.Фолкнер.
|
|
|
|
|
Jan 21 2007, 21:26
|
Местный
  
Группа: Свой
Сообщений: 351
Регистрация: 11-09-05
Из: Харьков
Пользователь №: 8 458

|
Цитата(InvisibleFed @ Jan 21 2007, 12:37)  Переключение тредов происходит гораздо быстрее. Что касается шедулинга, то на системном уровне его нет как такового (тред не является объектом ядра linux, насколько мне известно), управление на пользовательском уровне связано скорее с опытом. А по производительности - я уже свое мнение высказал. Цитата(makc @ Jan 21 2007, 13:03)  Вы прокакое ядро говорите? Если про 2.6, то чуть раньше мы тут уже выяснили, что в нем треды реализуются через процессы с разделяемым адресным пространством (и другими данными). Т.е. являются объектами шедулинга и, соотвественно, объектами ядра. Цитата(InvisibleFed @ Jan 21 2007, 15:07)  Я про 2.4. О тредах знает ТОЛЬКО процесс. Ядро о них ничего не знает. И шедулит оно только процессы. Все остальное - на уровне библиотеки. Процесс как таковой даже тела почти не имеет (я имею ввиду каких-то описательных структур). Если у ядра есть таблица процессов, то таблицы потоков у него нет. В 2.6, может, по другому (хотя я, если честно, в этом сомневаюсь). Робяты  ... POSIX, 1003b требует, чтобы для атрибутов потока могли быть установлены режимы решедулирования: int pthread_attr_setscope( pthread_attr_t* attr, PTHREAD_SCOPE_SYSTEM ); или int pthread_attr_setscope( pthread_attr_t* attr, PTHREAD_SCOPE_PROCESS ); - эти 2 и никаких больше: PTHREAD_SCOPE_SYSTEM (в рамках системы) и PTHREAD_SCOPE_PROCESS (в рамках заключающих потоки процессов) ... но 2-й способ ни в одной UNIX-like OS толком не реализован, а в Rationale к POSIX - выражается робкое сомнение как его можно реализовать вообще... И в Linux, как системе претендующей на POSIX OS, только более "колхозной"  - ничего другого быть не может, долгое время путаницу вносил механизм создания через clone, когда потоки и процессы создавались однотипно, "заказывая" им перечень атрибутов: немножко беременный / немножко не беременный  ... Из POSIX определения уже понятно, что именно только и исключительно потоки и могут быть объектом решедулирования. И поэтому потоки просто не могут не быть объектами ядра  ... Иллюзию путаницы здесь создаёт то, что всякий процесс, хотите вы того или нет  , имеет как минимум 1 поток - главный, main() - вот он у вас и решедулируется под видом процесса. А процесс - это просто мёртвая статическая оболочка над потоком, служащая менеджеру процессов для занесения туда статистической и учётной информации, типа "занимаемое процессорное время"... В других ОС, например QNX или Plan9 - это гораздо отчётливее видно, в Linux это смазывается его монолитным макроядром  .
|
|
|
|
|
Jan 21 2007, 23:35
|
Участник

Группа: Новичок
Сообщений: 30
Регистрация: 28-01-05
Пользователь №: 2 260

|
Кстати, раз пошла такая пьянка, может подскажет кто - что есть почитать на тему правильного написания программ с использованием всех имеющихся механизмов. Просто очень много литературы о том как создать механизм (т.е. драйвер), как работать с сокетами, тридами, синхронным и асинхронным I/O, с fork/exec и т.д. А о том что в каких местах применять - информации не нашел. Приходится пользоваться какими-то обрывочными сведениями.
Например, как решается задача планировки в user space? Допустим имеется последовательная шина, на которой висит несколько устройств с разным приоритетом опроса. Есть ли какие-то штатные средства для создания очереди запросов, возможно с различной приоритетностью и раздачи результатов тем кто ожидает результатов? Или как всегда все надо делать самому? Как правильно такие задачи декомпозировать в среде Linux?
Может есть что-то в качестве хорошего рабочего примера?
|
|
|
|
|
Jan 22 2007, 01:06
|
Местный
  
Группа: Свой
Сообщений: 351
Регистрация: 11-09-05
Из: Харьков
Пользователь №: 8 458

|
Цитата(path_finder @ Jan 22 2007, 00:35)  Кстати, раз пошла такая пьянка, может подскажет кто - что есть почитать на тему правильного написания программ с использованием всех имеющихся механизмов. Просто очень много литературы о том как создать механизм (т.е. драйвер), как работать с сокетами, тридами, синхронным и асинхронным I/O, с fork/exec и т.д. А о том что в каких местах применять - информации не нашел. Приходится пользоваться какими-то обрывочными сведениями. 1. посмотрите для начала: http://www.books.ru/shop/books/357604- и не потому, что это чем-то лучше, чем другие источники - но это результаты экспериментирования в коде, и коды эти все приведены, и результаты там совсем не ожидаемые и даже временами неожиданные - вы можете всё это повторить в своей любимой ОС  и проанализировать выявленные артефакты... 2. ... и конечно - 2 Стивенса  : У. Стивенс "UNIX: взаимодействие процессов" - СПб.: Питер, 2002 - 576 стр. У. Стивенс "UNIX: разработка сетевых приложений" - СПб.: Питер, 2003 - 1088 стр. (при чём здесь сетевые приложения?  - а при том, что основная доля асинхронностей и параллелизмов "вылезает" именно в сетевых приложениях). Цитата(path_finder @ Jan 22 2007, 00:35)  Например, как решается задача планировки в user space? Допустим имеется последовательная шина, на которой висит несколько устройств с разным приоритетом опроса. Есть ли какие-то штатные средства для создания очереди запросов, возможно с различной приоритетностью и раздачи результатов тем кто ожидает результатов? Или как всегда все надо делать самому? Как правильно такие задачи декомпозировать в среде Linux? 3. параллельность - это одно, а параллельность при вмешательстве приоритетов - это уже совсем другое; 1-е как нельзя лучше (даже исчерпывающе) проанализировано Э.Дейкстра и Хоаром (их публикации и результаты вы легко найдёте) - 2-е ... при наличии приоритетов очень сложно создать формальную модель (это не я оцениваю, а те кто работают в этой области) - посмотрите в сторону частотно-монотонной диспетчеризации, вот 2 перевода здесь: http://qnxclub.net/modules.php?name=Conten...wpage&pid=7(2 самых верхних  ).
|
|
|
|
|
Jan 22 2007, 10:53
|
Местный
  
Группа: Свой
Сообщений: 401
Регистрация: 18-11-06
Из: Хабаровск
Пользователь №: 22 469

|
Цитата Из POSIX определения уже понятно, что именно только и исключительно потоки и могут быть объектом решедулирования. И поэтому потоки просто не могут не быть объектами ядра ... Иллюзию путаницы здесь создаёт то, что всякий процесс, хотите вы того или нет , имеет как минимум 1 поток - главный, main() - вот он у вас и решедулируется под видом процесса. А процесс - это просто мёртвая статическая оболочка над потоком, служащая менеджеру процессов для занесения туда статистической и учётной информации, типа "занимаемое процессорное время"... А если у тебя внутри процесса несколько потоков (а не один main), кто их будет шедулить: библиотека или ядро (я имею ввиду планировщик ядра)? Я говорю - библиотека, никак не ядро. Слабо себе представляю в linux приоритет потоков не в рамках одного процесса. А ведь приоритет является основой шедулинга (пусть и условной). Цитата Здесь путаницу вносит видимо несколько реализаций тредов, которые имеются в linux'е - linuxthreads (2.4) и nptl (2.4/2.6) - счедулинг кажной треды или группового процесса присутствует о обеих реализациях. Только в первой он сделан в user-space с помощью дополнительной треды, со всеми вытекающими "особенностями", что видимо и вызывает справедливые нарекания программеров Чего за nptl? Можно поподробнее?
Сообщение отредактировал InvisibleFed - Jan 22 2007, 10:57
|
|
|
|
|
Jan 22 2007, 11:15
|
Местный
  
Группа: Свой
Сообщений: 351
Регистрация: 11-09-05
Из: Харьков
Пользователь №: 8 458

|
Цитата(InvisibleFed @ Jan 22 2007, 11:53)  А если у тебя внутри процесса несколько потоков (а не один main), кто их будет шедулить: библиотека или ядро (я имею ввиду планировщик ядра)? Я говорю - библиотека, никак не ядро. Слабо себе представляю в linux приоритет потоков не в рамках одного процесса. А ведь приоритет является основой шедулинга (пусть и условной). В нормальной реализации потоков (я не знаю, до какой степени уже "нормальная" реализация в Linux - некоторое время не смотрел в эту сторону, но она всё больше сдвигается в сторону "нормальной"  ) - "если у тебя внутри процесса несколько потоков"  - то шедулить их будет, конечно же - ядро  , потому что единицей шеулирования является поток, а вовсе не процесс, как раз о процессе ядро может и вообще ничего не знать: это знане нужно менеджеру процессов для запуска, завершения и корректировки статистики в ходе выполнения, не более. А вот как раз приоритет выполнения - он является состаной частью атрибутной записи потока - pthread_attr_t. Да кроме всего прочего, этот приоритет (и сделать это может только ядро ОС) время от времени системе (хорошей системе  ) придётся изменять без вашего ведома: ввеох-вниз, так что вы этого и не заметите без специальных усилий - при чисто статических приоритетах вы нарвётесь на инверсию пиоритетов (при 3-х и более процессов/потоков) и ... тю-тю  ... P.S. "нормальную" реализацию потоков, о которой я говорил выше, которая полностью соответствует POSIX реального времени - можем наблюдать в QNX ... рассмотревши её там - можно переносить аналогии и на Linux.
|
|
|
|
|
Jan 22 2007, 11:55
|
Местный
  
Группа: Свой
Сообщений: 351
Регистрация: 11-09-05
Из: Харьков
Пользователь №: 8 458

|
Зесь уже очень верно заметили раньше: Цитата(AlexandrY @ Jan 18 2007, 19:02)  Процессы и потоки выдумка Linux-а. Там процессы настолько медленно переключаются, что пришлось придумать потоки. В без MMU-ушных процах в RTOS процесы и потоки это одно и тоже и называются обычно задачами. - на предмет того, что без MMU и изолированого адресного пространства - например в MS-DOS - различать процессы и потоки невозможно, это одно и то же; как, в частности, и обработчики IRQ, кстати, которые и есть прародителем-моделью потока... Хотя и не одно и то же - текстуально, в коде: переменные-объекты потоков находятся в общем поле видимости, но если отбросить это малое различие, то потоки/процессы MS-DOS могли бы разделять переменные по фиксированным адресам, например - вот эта "видимость" и есть главной причиной "придумывания" потоков ... а не время переключения контекста: о разительной разнице времён переключения контекстов потоков/процессов - это красивая народная легенда ... преподаватели ВУЗов её часто "доносят"  студентам - поскольку "на хлопський розум" это так и выглядит, а руками преподаватели, обычно, свои предположения не перепроверяют  ... Так же неверно и предположение: "Процессы и потоки выдумка Linux-а" - идея потоков присутствовали в AIX & Solaris, да и в других, когда и Linux то ещё "не придумали"
|
|
|
|
|
Jan 23 2007, 05:17
|
Местный
  
Группа: Свой
Сообщений: 401
Регистрация: 18-11-06
Из: Хабаровск
Пользователь №: 22 469

|
Цитата В нормальной реализации потоков (я не знаю, до какой степени уже "нормальная" реализация в Linux - некоторое время не смотрел в эту сторону, но она всё больше сдвигается в сторону "нормальной" ) - "если у тебя внутри процесса несколько потоков" - то шедулить их будет, конечно же - ядро , потому что единицей шеулирования является поток, а вовсе не процесс, как раз о процессе ядро может и вообще ничего не знать: это знане нужно менеджеру процессов для запуска, завершения и корректировки статистики в ходе выполнения, не более. А вот как раз приоритет выполнения - он является состаной частью атрибутной записи потока - pthread_attr_t. Да кроме всего прочего, этот приоритет (и сделать это может только ядро ОС) время от времени системе (хорошей системе ) придётся изменять без вашего ведома: ввеох-вниз, так что вы этого и не заметите без специальных усилий - при чисто статических приоритетах вы нарвётесь на инверсию пиоритетов (при 3-х и более процессов/потоков) и ... тю-тю ...
P.S. "нормальную" реализацию потоков, о которой я говорил выше, которая полностью соответствует POSIX реального времени - можем наблюдать в QNX ... рассмотревши её там - можно переносить аналогии и на Linux. Последний раз писал потоки около года назад в linux 2.4, используя именно pthread_*. Все-таки "как должно быть" и "как есть" - разные вещи. Мы говорим об одних и тех же вещах на разных языках. Выдержки из книги "Программирование под Linux. Профессиональный подход.": "... Потоковые функции, соответствующие стандарту Posix, реализованы в Linux не так, как в большинстве других версий Unix. Суть в том, что в Linux потоки реализованы в виде процессов. Когда вызывается функция pthread_create(), операционная система на самом деле создает новый процесс, выполняющий поток. Но это не тот процесс, который создается функцией fork(). Он, в частности, делит общее адресное пространство и ресурсы с исходным процессом, а не получает их копии." От себя добавлю, что при переключении потоков требуется изменять гораздо меньше структур и данных, чем при переключении процессов. Ведь если подумать, зачем все эти исключения, взаимоблокировки, семафоры, если операционка сама взяла и распланировала как ей вздумается, и плевала она на мои семафоры. Русурсы в системе выделяются процессу, пользует их процесс, приоритет выставляется - процессу, а значит, я считаю, и объектом ядра является именно процесс. Планирование в системах реального времени - это ваще отдельная песня. Вы правы, система реального времени не должна допускать взаимоблокировок НИКОГДА. И часто, при определенной настройке ("жесткая" система реального времени, "мягкая"), она может послать юзера с его планированием, чтобы только не допустить собственного краха. Вероятно в QNX Posix реализован не так как в Linux.
|
|
|
|
|
Jan 23 2007, 11:36
|
Местный
  
Группа: Свой
Сообщений: 351
Регистрация: 11-09-05
Из: Харьков
Пользователь №: 8 458

|
Цитата(InvisibleFed @ Jan 23 2007, 06:17)  Все-таки "как должно быть" и "как есть" - разные вещи. Конечно разные: всякая вещь должна быть такой "как должно быть", а то "как есть" в отличие от "как должно быть" - это всё херня  Цитата(InvisibleFed @ Jan 23 2007, 06:17)  Мы говорим об одних и тех же вещах на разных языках. Выдержки из книги "Программирование под Linux. Профессиональный подход.":
"... Потоковые функции, соответствующие стандарту Posix, реализованы в Linux не так, как в большинстве других версий Unix. Суть в том, что в Linux потоки реализованы в виде процессов. Когда вызывается функция pthread_create(), операционная система на самом деле создает новый процесс, выполняющий поток. Но это не тот процесс, который создается функцией fork(). Он, в частности, делит общее адресное пространство и ресурсы с исходным процессом, а не получает их копии." Нет, мы говоим об одних вещах на разных языках: то, что цитируется из книжки (этой книжке в прошлую пятницу 10 лет исполнилось  ) - относится как раз к "старой" реализации через clone, а то, что автор называет "не так" - правильнее называть "через задницу" ... о чём, впрочем, уже писано-переписано в публикациях, и от чего разработчики Linux уходят. Цитата(InvisibleFed @ Jan 23 2007, 06:17)  От себя добавлю, что при переключении потоков требуется изменять гораздо меньше структур и данных, чем при переключении процессов. Да, но вы забываете, что в подавляющем большинстве случаев (практически всех кроме sched_yield и перехода в блокированное состояние типа sleep()) - переключение потоков (именно потоков, потому что переключение процессов - это фикция, процессы - это статическая сущность, оболочка) - происходит по системному тику, одновременно с которым происходит отработке службы времени и перепланирования, требующие времени T, которое на порядок или около того больше времени переключения контекстов t (будь это переключение хоть в рамках единого адресного пространства, хоть разных, т.е. между потоками), но кроме того, на перепланирование в любом случае происходит переключение в контекст ядра и кольцо защиты 0, так что практически одинаково куда потом возвращаться.... Это так, в общих чертах ... но я это проверял, в цифрах и не раз, и для различных (ну пусть "некоторых") ядер Linux и для QNX. Почему и говорю: мнение о "разительной" разнице переключений между потоками внутри одного процесса и в разных процессах - красивая народная легенда. Цитата(InvisibleFed @ Jan 23 2007, 06:17)  Ведь если подумать, зачем все эти исключения, взаимоблокировки, семафоры, если операционка сама взяла и распланировала как ей вздумается, и плевала она на мои семафоры. Русурсы в системе выделяются процессу, пользует их процесс, приоритет выставляется - процессу, а значит, я считаю, и объектом ядра является именно процесс. Здесь вообще полная "каша": - ОС ведёт планирование только и именно в тех рамках, в которых ей позволяют ей текущие состояния примитивов синхронизации... а не "как ей вздумается"... - ... а вы слышали, например, что захваченный мютекс всегда имеет "хозяина", и только он может разблокровать мютекс, и хозяин этот - всегда поток, и его pid_t просто прописывается в структуре мютекса, см. *.h определения... - приоритеты, к примеру, также устанавливаются потокам: в рамках 1-го процесса может крутиться N потоков с N различными приоритетами ... более того, при взаимодействии потоко эти приоритеты могут плыть вверх-вниз (о наследовании приоритетов и граничных приоритетах - слышали?), так что ни вы ни процесс этого и не заметит, а если захотите - то и тогда не сможете вмешаться  Цитата(InvisibleFed @ Jan 23 2007, 06:17)  Планирование в системах реального времени - это ваще отдельная песня. Вы правы, система реального времени не должна допускать взаимоблокировок НИКОГДА. И часто, при определенной настройке ("жесткая" система реального времени, "мягкая"), она может послать юзера с его планированием, чтобы только не допустить собственного краха. Да нет там никаких песен - все дисциплины и процедуры планирования описаны POSIX и его расширениями, и ничего, кроме FIFO - раунд-робин - адаптивной - спорадической диспетчеризации (с тонкими отличиями в деталях реализации) никто и нигде не придумал. А система, которая может "послать юзера" ? ... "пикантно, пикантно...."(с) - поручик Ржевский ... кто вам такие страсти рассказал? может это было в качестве анекдота? Цитата(InvisibleFed @ Jan 23 2007, 06:17)  Вероятно в QNX Posix реализован не так как в Linux. Не вероятно, а точно  : - POSIX, и особенно его последние расширения (1003b и др.) - в QNX реалиованы гораздо строже и (почти) в полном соответствии.
|
|
|
|
|
Jan 23 2007, 13:34
|
Местный
  
Группа: Свой
Сообщений: 401
Регистрация: 18-11-06
Из: Хабаровск
Пользователь №: 22 469

|
Цитата этой книжке в прошлую пятницу 10 лет исполнилось Книжке 6 лет. Интересно, сколько лет ядру 2.4 со всеми его реинкарнациями? Цитата Да нет там никаких песен - все дисциплины и процедуры планирования описаны POSIX и его расширениями, и ничего, кроме FIFO - раунд-робин - адаптивной - спорадической диспетчеризации (с тонкими отличиями в деталях реализации) никто и нигде не придумал. А система, которая может "послать юзера" ? ... "пикантно, пикантно...."(с) - поручик Ржевский ... кто вам такие страсти рассказал? может это было в качестве анекдота? Даже и не знаю чего сказать. Как будто процессорное время - это один единственный ресурс в системе. Может Вы знаете алгоритм планирования с заданным максиамльным временем отклика и 100%-но не допускающий взаимоблокировок? Вообщем, спор надоел, а Цитата Конечно разные: всякая вещь должна быть такой "как должно быть", а то "как есть" в отличие от "как должно быть" - это всё херня не херня, а реалии жизни. Чем больше живешь тем больше убеждаешься. А поптом через 10 лет конторы вдруг заявит: вот, это как раз то что мы задумали еще ТОГДА..." (Как Microsoft делает с выходом каждой новой ОС).
|
|
|
|
|
Jul 4 2007, 17:39
|
Частый гость
 
Группа: Свой
Сообщений: 140
Регистрация: 18-10-05
Пользователь №: 9 792

|
Цитата(makc @ Jan 21 2007, 18:25)  Насколько я понял, в старой реализации linuxthread (которую я собственно юзаю) поток представлял из себя процесс с расшаренным адресным пространством. Плюс в каждом процессе запускался еще один поток для присмотра за остальными. Таким образом, scheduling делало все-таки ядро (это мне нравится), но работать это может только в однопроцессорной системе (на это мне наплевать). И еще для политики SCHED_OTHER приоритет может быть только 0. Так?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|