#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 исправляет это поведение.
Комментариев нет:
Отправить комментарий