Страницы

Поиск по вопросам

пятница, 20 декабря 2019 г.

Уточнение по поводу posix_threads в linux

#linux #c #многопоточность #pthread


Хотел разобраться что за легковесные потоки, в итоге полнейшая каша в голове стала
еще гуще... читал тут книгу У. Ричард Стивенс, Стивен А. Раго "UNIX. Профессиональное
программирование", там был кусок:

pthread_t ntid;
void
printids(const char *s)
{
    pid_t pid;
    pthread_t tid;
    pid = getpid();
    tid = pthread_self();
    printf("%s pid %u tid %u (0x%x)\n", s, (unsigned int)pid,
       (unsigned int)tid, (unsigned int)tid);
}
void* thr_fn(void *arg)
{
printids("новый поток: ");
return((void *)0);
}
int
main(void)
{
    int err;
    err = pthread_create(&ntid, NULL, thr_fn, NULL);
    if (err != 0)
        err_quit("невозможно создать поток: %s\n", strerror(err));
    printids("главный поток:");
    sleep(1);
    exit(0);
}


И в linux это выводило следующее:

$ ./a.out
новый поток:   pid 6628 tid 1026 (0x402)
главный поток: pid 6626 tid 1024 (0x400)


Т.е. для каждого потока process id разные из-за того что при pthread_create используется
системный вызов clone() типа это тоже своеобразный процесс... И в итоге теперь не понятно:
есть ли вообще в линуксе нити в общепринятом представлении, т.е. у нитей общее адресное
пространство, но свой стек, у процессов разные адресные пространства.

Гугление очень запутало: где-то говорится, что posix threads в линуксе работают лишь
в пространстве ядра, где-то, что в пользовательском пространстве, где-то, что и там
и там. Я считал что в и там и там исполняются лишь процессы.

Посему вопросы:


нативный тред в линуксе исполняется в пространстве пользователя или в пространстве ядра? 
есть ли вообще нативный тред в линуксе и является ли он легковесным процессом

    


Ответы

Ответ 1



Да, есть native threads как результат вызова clone(), и они (в реализации pthread) исполняются в пространстве пользователя, являясь легковесными процессами (по крайней мере в том смысле, что кванты времени CPU им выделяются тем же планировщиком ядра, что и остальным процессам). У каждого такого потока свой стек (в общем адресном пространстве), маска сигналов, переменная errno (и м.б. еще несколько ресурсов, см. подробнее в pthreads(7) - Linux man page).

Ответ 2



Я подозреваю, что вы имеете дело со старинными LinuxThreads или с какой-то попыткой эмулировать их поведение в целях обратной совместимости. Уже в версии ядра 2.6 линукс должен был перейти на NPTL (Native POSIX Thread Library), которая в соответствии с требованиями POSIX обязана возвращать одно и то же значение getpid() из всех потоков одного процесса. http://www.drdobbs.com/open-source/nptl-the-new-implementation-of-threads-f/184406204 См. "Migrating to NPTL" getpid() В LinuxThreads, в нарушение стандарта POSIX, системный вызов getpid() возвращает разные значения ID для разных потоков. NPTL исправляет это поведение.

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

Отправить комментарий