Системный вызов clone вызывает do_fork, waitpid вызывает do_wait.
Если clone порождает пять процессов, из которых два с флагами CLONE_THREAD.
Значит ли это, что waitpid(getpid(), &status, __WALL) вернёт информацию, по всем child? У меня не получается, пишет no child process.
С моей точки зрения waitpid имеет право игонорировать ghjwtccs clone c CLONE_THREAD, учди waitpid вызывается без флага __WALL и с флагом __WNOTHREAD.
Что я не допонимаю? Что нужно просмотреть, пррочитать для проработки вопроса?
Где описаны структуры thread_info и list_head?
вопрос уж очень заковыристо сформулирован, не уверен, что понял правильно.
если p делает CLONE_THREAD то он не может видеть нить с помощью do_wait()
по двум причинам:
1. do_wait() работает с процессами (thread group), а не с нитями,
поэтому он их просто "пропускает". исключение: p делает ptrace
на эту нитку. см. eligible_child(), проверка ->exit_signal.
2. do_wait() работает с теми процессами, для которых caller является
родителем (или, опять-таки, ptracer). parent'ом нашей нити является
не p, а p->parent.
thread_info в include/asm/thread_info.h, list_head в include/linux/list.h,
но это не при чем.
Пользую ядро 2.6.18 gentoo
1. в do_wait есть условие на флаг __WNOTHREAD, если его нет, то вызывается фугкция next_thread, в которой макрос по идее должен возращать указатель на тред. Но у меня и с __WALL пока не получается получит инфу о потоке.
2. согласен, так в мане, так получается и по тестам
Пользую ядро 2.6.18 gentoo 1. в do_wait есть условие на флаг __WNOTHREAD, если его нет, то вызывается фугкция next_thread, в которой макрос по идее должен возращать указатель на тред. Но у меня и с __WALL пока не получается получит инфу о потоке. 2. согласен, так в мане, так получается и по тестам
Пользую ядро 2.6.18 gentoo
1. в do_wait есть условие на флаг __WNOTHREAD, если его нет, то вызывается фугкция next_thread, в которой макрос по идее должен возращать указатель на тред. Но у меня и с __WALL пока не получается получит инфу о потоке.
2. согласен, так в мане, так получается и по тестам
2all:
Ссори, за дурное форматирование текста
> 1. в do_wait есть условие на флаг __WNOTHREAD ...
это не то. __WNOTHREAD означает, что нам нужны только потомки,
созданные (forked) именно этой нитью (caller). да, next_thread()
вызывается, но результат не является "фигурантом" do_wait().
те, мы смотрим не на "tsk", а на "tsk->children".
мда. обьяснение то еще. просто посмотрите на код внимательнее,
он довольно простой.
> Как же тогда родитель может ожидать изменения состояния своего
> потомка, если порождённый потомок формально не является потомком
> родителя?
не "формально не является", а просто не является :)
ядро предоставляет CLONE_CHILD_CLEARTID. ничего не знаю про libpthread,
но думаю что всякие "join" реализованы именно так.
> Моя работа заключается в проверке системных вызовов ядра.
можно чуть подробнее? мне тоже стало любопытно... где и кто
это у нас занимается валидацией такого рода?
>tsk->children
Точно :)
>мда. обьяснение то еще. просто посмотрите на код внимательнее,
он довольно простой.
в общем то да, но не осознавая идеолгоии сложно врубиться что и зачем всё это делается... По моим представлениям фокусы с порожденим процессов, получением состояниях, pid, потоки, тредовые группы в нутри ядра и доступ снаружи... не очень хорошо документированы :(
в чужом коде копаться всегда тяжелее, чем в своём :D
>ничего не знаю про libpthread,
но думаю что всякие "join" реализованы именно так.
читая книгу Роберта Лава прихожу к выводу, что вс1ё на основе clone, правда он тоже, как и многие не влезает в дебри pid, thread_group, где на что влияют флаги clone и do_wait... и прочие дебри :(
libpthread вроде как создает прикладные потоки, о которых ядро ничего не знает. clone - это для другого сорта потоков, так называемых легковесных процессов (LWP), которыми управляет ядро.
Просто сам пользовательский процесс создает внутри себя несколько контекстов выполнения и самостоятельно их планирует (все эти фичи предоставляются библиотекой ptherad). А ядро все это не видит, оно видит только одно то пользовательское приложение, и планирует его как одно приложения (выделяет один квант на всех, и его не волнует, как пользовательские потоки будут за него драться).
Второй способ родить поток в Линуксе - это при помощи clone (библиотека
pthread тут уже не при чем imho). Этот clone рожает потоки, которые уже
планируются ядром (т.е. на них честно заводится 2-килобайтная task_struct, они ставятся в очередь, и т.д.)
> libpthread вроде как создает прикладные потоки, о которых ядро ничего не знает.
> clone - это для другого сорта потоков, так называемых легковесных процессов (LWP),
> которыми управляет ядро.
нет, это не так. linux (и LinuxThreads, и NPTL) используют 1:1 модель, все потоки
создаются с помощью clone() и видны ядру.
я говорил о конкретном флаге CLONE_CHILD_CLEARTID, он дает возможность получить
уведомление (FUTEX_WAKE) при завершении задачи (напр нити), скорее всего join
этот механизм и использует.