Как я могу определить, является ли pthread_self основным (первым) потоком в процессе? - PullRequest
9 голосов
/ 01 февраля 2011

справочная информация: я работаю над библиотекой журналов, которая используется многими программами.
Я назначаю удобочитаемое имя для каждого потока, основной поток должен получить "main", но я бы хотелчтобы иметь возможность обнаруживать это состояние из библиотеки, не требуя кода в начале каждой функции main ().

Также обратите внимание: код библиотеки не всегда будет вводиться первым из основного потока.

Ответы [ 3 ]

13 голосов
/ 02 февраля 2011

Это довольно выполнимо, в зависимости от платформы, на которой вы работаете, но абсолютно никак не переносимым и универсальным способом ...

Кажется, что Mac OS X - единственный с прямым и документированным подходомв соответствии с их pthread.h файлом:

/* returns non-zero if the current thread is the main thread */
int pthread_main_np(void);

Я также обнаружил, что FreeBSD имеет заголовок pthread_np.h, который определяет pthread_main_np (), так что это должно работать и во FreeBSD (8.1как минимум), а в OpenBSD (как минимум 4.8) pthread_main_np () также определена в pthread.h.Обратите внимание, что _np явно означает непереносимый!

В противном случае единственный более общий подход, который приходит на ум, - это сравнение PID процесса с TID текущего потока, если они совпадают, этого потокаэто главное.Это не обязательно работает на всех платформах, это зависит от того, можете ли вы вообще получить TID (вы не можете, например, в OpenBSD), и если вы это сделаете, имеет ли он какое-либо отношение к PID или еслиПодсистема потоков имеет свой собственный учет, который не обязательно связан.

Я также обнаружил, что некоторые платформы возвращают постоянные значения в виде TID для основного потока, поэтому вы можете просто проверить их.

Краткое описание платформ, которые я проверил:

  • Linux: возможно здесь , syscall (SYS_gettid) == getpid () - это то, что вам нужно
  • FreeBSD: здесь невозможно, thr_self () кажется случайным и не имеет отношения к getpid ()
  • OpenBSD: здесь невозможно, нет способа получить TID
  • NetBSD: возможно здесь, _lwp_self () всегда возвращает 1 для основного потока
  • Solaris: возможно здесь , pthread_self () всегда возвращает 1 для основного потока

Таким образом, в основном вы должны быть в состоянии сделать это непосредственно наMac OS X, FreeBSD и OpenBSD.

Вы можете использовать подход TID == PID в Linux.

Вы можете использовать подход TID == 1 в NetBSD и Solaris.

Надеюсь, это поможет, хорошего дня!

8 голосов
/ 02 февраля 2011

Вызовите pthread_self () из main () и запишите результат. Сравните будущие вызовы pthread_self () с вашим сохраненным значением, чтобы узнать, находитесь ли вы в главном потоке.

0 голосов
/ 02 февраля 2011

Вы можете использовать некоторый ресурс общего имени, который позволяет потокам, которые порождают, зарегистрировать имя (возможно, карту идентификатора потока для имени).Ваша система журналирования может затем поместить вызов в метод, который получает имя через идентификатор потока в поточно-безопасном режиме.

Когда поток умирает, он должен удалить свое имя из сопоставления, чтобы избежать утечки памяти.

Этот метод должен позволять именовать все потоки, а не только главные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...