2009-02-17 16 views
33

Mam pthread_t i chciałbym zmienić jego powinowactwo do procesora. Problem polega na tym, że używam glibc 2.3.2, który nie ma pthread_setaffinity_np(). Jest to jednak w porządku, ponieważ pthread_setaffinity_np() samo jest opakowaniem sched_setaffinity(), które można wywołać, przekazując identyfikator wątku zamiast identyfikatora procesu, aby ustawić powinowactwo dla dowolnego wątku.Jak uzyskać identyfikator wątku z dowolnego pthread_t?

ALE ... Identyfikator wątku, z którym może współpracować sched_setaffinity, jest identyfikatorem wątku systemu operacyjnego, który można pobrać z wywołania systemowego gettid(). To różni się od nieprzezroczystego typu pthread_t, a gettid() zwróci tylko identyfikator wątku bieżącego wątku . Muszę umieć ustawić powinowactwo procesora do dowolnego wątku.

Niestety, nie mogę uzyskać dostępu do prywatnych części pthread, które pozwoliłyby ukraść identyfikator wątku, przesyłając pthread_t do struct pthread *. Wydaje mi się, że tym lepiej, ponieważ poleganie na prywatnych implementacjach wymaga nawet problemów z więcej.

Czytałem również na temat funkcji pthread_getunique_np, jednak zwraca to "unikalny integralny identyfikator" - które nie sądzę, jest w jakimkolwiek kształcie lub formie równoważnej identyfikator wątku systemu operacyjnego.

W związku z tym pytanie: Jak mogę uzyskać identyfikator wątku z dowolnego pthread_t?

Odpowiedz

31

Od pthread y nie muszą być realizowane z wątków Linux (lub wątków jądra w ogóle, jeśli o to chodzi), a niektóre implementacje są całkowicie na poziomie użytkownika lub zmieszaniu pthread s interfejs nie zapewnia funkcje dostępu do tych szczegóły implementacji, ponieważ te nie byłyby przenośne (nawet w implementacjach pod Linux-em w wersjach pthread). Biblioteki wątków, które ich używają, mogą zapewniać to jako rozszerzenie, ale nie wydaje się, żeby to miało miejsce.

Oprócz dostępu do wewnętrznych struktur danych biblioteki wątków (czego, jak zrozumiałe nie chcesz, chociaż przy założeniach dotyczących powinowactwa procesora i identyfikatorów wątków systemu Linux, Twój kod nie będzie przenośny), możesz być w stanie odtwarzać Sztuką w momencie tworzenia, jeśli kontrolować kod, który tworzy wątki:

Give pthread_create() funkcję wejścia, który wywołuje gettid() (który nawiasem mówiąc jest prawdopodobne, aby zrobić używając syscall makro bezpośrednio, ponieważ nie zawsze jest eksportowana przez libc), gdzieś zapisuje wynik, a następnie wywołuje oryginalną funkcję wprowadzania. Jeśli masz wiele wątków z tą samą funkcją wejścia, możesz przekazać inkrementowany wskaźnik do tablicy w argumencie do pthread_create, który następnie zostanie przekazany do funkcji wprowadzania utworzonej w celu przechowywania identyfikatora wątku. Przechowaj wartość zwracaną pthread_t z pthread_create w tej samej kolejności, a następnie będzie można wyszukać identyfikatory wątków systemu Linux wszystkich utworzonych wątków ze względu na ich wartość pthread_t.

To, czy ta wartość jest tego warta, zależy od tego, jak ważne jest ustawienie powinowactwa procesora w danym przypadku, w przeciwieństwie do braku dostępu do wewnętrznych struktur biblioteki wątków lub w zależności od biblioteki wątków, która zapewnia pthread_setaffinity_np.

1

Proponuję proste obejście tego problemu z udostępnioną tablicą int, w której można napisać identyfikator wątku z wątków, aby uzyskać do niego dostęp później.

Nadzieję, że pomaga.

+1

Nie ma potrzeby mmap, wątki i tak dzielą tę samą pamięć. – raimue

+0

Dobry punkt :) gosh, który jest tak oczywisty ...;) –

2
pthread_t pthread_self() 

to powrót aktualny pthread_t, czyli identyfikator wątku, można przekonwertować go do typu „unsigned int”,

+2

Właściwie "unsigned long int". – JumpAlways

+0

'pthread_t me();' => niezdefiniowane odwołanie do 'me()'. – Eric

12

Właściwie pthread_self zwrotów pthread_t a nie całkowitą wątek id można pracować, następnego pomocnika Funkcja dostarczy Ci to w przenośny sposób przez różne systemy POSIX.

uint64_t gettid() { 
    pthread_t ptid = pthread_self(); 
    uint64_t threadId = 0; 
    memcpy(&threadId, &ptid, std::min(sizeof(threadId), sizeof(ptid))); 
    return threadId; 
} 
+0

'pthread_t tid = pthread_self();' działa na głównym wątku, ale nie na innym? Mam awarię exe wywołującą to z '__start_routine' po wywołaniu' pthread_create'. – Eric

0

W glibc 2.24pthread_t zwracany jest po prostu wskaźnik do nieprzezroczystej struct pthread. Możesz sprawdzić definicję w nptl/descr.h.

Powiązane problemy