Як надрукувати ідентифікатор потоку потоку, створеного бібліотекою pthread, у програмі linux c?
наприклад: ми можемо отримати процес процесу за допомогоюgetpid()
Як надрукувати ідентифікатор потоку потоку, створеного бібліотекою pthread, у програмі linux c?
наприклад: ми можемо отримати процес процесу за допомогоюgetpid()
Відповіді:
pthread_self()
функція дасть ідентифікатор потоку поточного потоку.
pthread_t pthread_self(void);
pthread_self()
Функція повертає PTHREAD дескриптор викликає потоку. Функція pthread_self () НЕ повертає інтегральний потік викликаючого потоку. Ви повинні використовувати, pthread_getthreadid_np()
щоб повернути інтегральний ідентифікатор потоку.
ПРИМІТКА:
pthread_id_np_t tid;
tid = pthread_getthreadid_np();
значно швидше, ніж ці дзвінки, але забезпечує однакову поведінку.
pthread_id_np_t tid;
pthread_t self;
self = pthread_self();
pthread_getunique_np(&self, &tid);
pthread_threadid_np
. Потрібно використовувати для проекту, тому потрібно перевірити надійність цього API на платформах iOS та OSX. Посилання посилалося на opensource.apple.com/source/Libc/Libc-583/pthreads/pthread.h, але не впевнений, що вони правильні.
_np
означає , що це не портативний. У Linux є свої _np
речі, але вони не включають Apple pthread_getthreadid_np
.
Що? Людина запитувала конкретний Linux та еквівалент getpid (). Не BSD чи Apple. Відповідь gettid () і повертає інтегральний тип. Вам доведеться викликати його за допомогою syscall (), ось так:
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
....
pid_t x = syscall(__NR_gettid);
Незважаючи на те, що це може бути не портативним для систем, що не є Linux, threadid є безпосередньо порівнянним і дуже швидким для отримання. Його можна надрукувати (наприклад, для журналів) як звичайне ціле число.
getpid()
було подано як приклад. Це не означало, що семантика є жорсткою специфікацією. Поінформованість людей про те, що вони роблять речі, сумісні з POSIX, щоб інші спільноти, крім Linux (наприклад, FreeBSD, Illumos, OS X тощо) могли отримати від них користь, це не "показ". Як я вже сказав, я думаю, Linux справді став наступною Windows.
Як зазначалося в інших відповідях, pthreads не визначає незалежний від платформи спосіб отримання інтегрального ідентифікатора потоку.
У системах Linux ви можете отримати ідентифікатор потоку таким чином:
#include <sys/types.h>
pid_t tid = gettid();
На багатьох платформах, що базуються на BSD, ця відповідь https://stackoverflow.com/a/21206357/316487 дає непереносимий спосіб.
Однак якщо причина, по якій ви вважаєте, що вам потрібен ідентифікатор потоку, полягає в тому, щоб знати, чи працює ви в тому ж або іншому потоці в іншому потоці, який ви контролюєте, ви можете знайти деяку утиліту в цьому підході
static pthread_t threadA;
// On thread A...
threadA = pthread_self();
// On thread B...
pthread_t threadB = pthread_self();
if (pthread_equal(threadA, threadB)) printf("Thread B is same as thread A.\n");
else printf("Thread B is NOT same as thread A.\n");
Якщо вам просто потрібно знати, чи ви в основному потоці, є додаткові способи, задокументовані у відповідях на це питання, як я можу зрозуміти, чи pthread_self є основним (першим) потоком у процесі? .
pthread_getthreadid_np
не було на моєму Mac os x. pthread_t
є непрозорим типом. Не бий головою над цим. Просто призначте це void*
і назвіть хорошим. Якщо вам потрібно printf
використовувати %p
.
Я думаю, що питання не тільки незрозуміле, але більшість людей також не усвідомлюють різниці. Вивчіть наступну приказку:
Ідентифікатори потоків POSIX не збігаються з ідентифікаторами потоків, що повертаються специфічним
gettid()
системним викликом Linux . Ідентифікатори потоків POSIX присвоюються та підтримуються реалізацією потоків. Ідентифікатор потоку, що повертається,gettid()
- це число (подібне до ідентифікатора процесу), яке присвоюється ядром. Хоча кожен потік POSIX має унікальний ідентифікатор потоку ядра в реалізації потоків Linux NPTL, програма, як правило, не повинна знати про ідентифікатори ядра (і не буде портативною, якщо це залежить від їх знання).Витримано з: Інтерфейс програмування Linux: Підручник з системного програмування для Linux та UNIX, Майкл Керріск
IMHO, є лише один портативний спосіб, який передає структуру, в якій визначають змінну, що містить номери за зростанням, наприклад, 1,2,3...
до кожного потоку. Роблячи це, ідентифікатор потоків можна відстежувати. Тим не менше, int pthread_equal(tid1, tid2)
слід використовувати функцію.
if (pthread_equal(tid1, tid2)) printf("Thread 2 is same as thread 1.\n");
else printf("Thread 2 is NOT same as thread 1.\n");
gettid()
насправді хороша пропозиція, дякую! Однак мені потрібно було слідувати відповіді Сергія Л. тут: stackoverflow.com/a/21280941/2430526
Існує також інший спосіб отримання ідентифікатора потоку. Під час створення потоків за допомогою
int pthread_create(pthread_t * thread, const pthread_attr_t * attr, void * (*start_routine)(void *), void *arg);
виклик функції; перший параметр pthread_t * thread
- це фактично ідентифікатор потоку (тобто беззнаковий довгий int, визначений у bits / pthreadtypes.h). Крім того, останній аргумент void *arg
- це аргумент, який передається void * (*start_routine)
функції для потокової обробки.
Ви можете створити структуру для передачі декількох аргументів і надіслати вказівник на структуру.
typedef struct thread_info {
pthread_t thread;
//...
} thread_info;
//...
tinfo = malloc(sizeof(thread_info) * NUMBER_OF_THREADS);
//...
pthread_create (&tinfo[i].thread, NULL, handler, (void*)&tinfo[i]);
//...
void *handler(void *targs) {
thread_info *tinfo = targs;
// here you get the thread id with tinfo->thread
}
Ви також можете писати таким чином, і він робить те саме. Наприклад, наприклад:
for(int i=0;i < total; i++)
{
pthread_join(pth[i],NULL);
cout << "SUM of thread id " << pth[i] << " is " << args[i].sum << endl;
}
Ця програма встановлює масив pthread_t і обчислює суму по кожному. Отже, це друк суми кожного потоку з ідентифікатором потоку.
Незалежний від платформи спосіб (починаючи з c ++ 11):
#include <thread>
std::this_thread::get_id();
pthread_t
. На mac, який буде вказівником, а на Linux цілим числом. Він також не відображає "рідний" ідентифікатор, який ви могли б бачити, top
наприклад. Щось, про що слід знати, але, можливо, це чудово для деяких цілей.