Pthread id из pthread_self () не соответствует данным из скрипта dtrace - PullRequest
3 голосов
/ 26 августа 2009

Я использую этот сценарий dtrace из здесь , чтобы попытаться найти, когда происходит переключение контекста для потоков Java-программы.

Я пытаюсь сопоставить данные, собранные из скрипта, с данными трассировки, собранными из работающей программы (например, методы входа / выхода). Я получаю идентификатор pthread запущенного потока, используя короткий метод JNI, который просто возвращает значение pthread_self ().

Проблема, с которой я столкнулся, заключается в том, что идентификатор потока, который я получаю при вызове pthread_self (), полностью отличается от идентификатора потока, который я получаю в сценарии dtrace. Мне интересно, если это потому, что я неправильно вызываю pthread_self (), так как он возвращает указатель, однако было трудно найти информацию о том, что на самом деле pthread_t на Mac OSX.

Ответы [ 4 ]

3 голосов
/ 15 сентября 2009

Итак, я отвечу на свой вопрос: переменные curthread и tid в dtrace являются значениями указателей для структур потоков ядра, чтобы получить эти значения для сравнения dtrace с данными потоков пространства пользователя, которые мне нужно было создать для расширения ядра эти внутренние значения для потоков в пользовательском пространстве.

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

2 голосов
/ 07 сентября 2009

С /usr/include/pthread.h:

typedef __darwin_pthread_t pthread_t;

затем от /usr/include/sys/_types.h:

struct _opaque_pthread_t {
  long __sig;
  struct __darwin_pthread_handler_rec* __cleanup_stack;
  char __opaque[__PTHREAD_SIZE__];
};
typedef struct _opaque_pthread_t* __darwin_pthread_t;

Исходный код вашего друга:)

1 голос
/ 30 мая 2013

Как насчет чего-то более элегантного, используя провайдера pid, который имеет дело с кодом пользователя?

# dtrace -n 'pid$target::pthread_self:return {printf("%p", arg1)}' -c 'java'
dtrace: description 'pid$target::pthread_self:return ' matched 1 probe
dtrace: pid 87631 has exited
CPU     ID                    FUNCTION:NAME
  0  90705              pthread_self:return 1053a7000
  0  90705              pthread_self:return 1054ad000
  2  90705              pthread_self:return 7fff7b479180
  2  90705              pthread_self:return 7fff7b479180
  2  90705              pthread_self:return 7fff7b479180
  2  90705              pthread_self:return 7fff7b479180
  2  90705              pthread_self:return 7fff7b479180
  4  90705              pthread_self:return 10542a000
  4  90705              pthread_self:return 10542a000

ура!

arg1 относится к возвращаемому значению в датчике, которое в этом случае является указателем. Если вам нужен материал, на который он указывает, используйте copyin(arg1, size_of_struct) и приведите результат к тому, что вы думаете (см. Сообщение @ Nikolai и не забывайте, что вы можете использовать #include в сценариях DTrace, если вы помните -C опция в командной строке). Имя поставщика pid$target расширяется до pid1234, где 1234 - это идентификатор процесса команды, выполняемой с параметром -c - в данном случае java.

Для получения дополнительной информации посетите Блог Брендана Грегга (который является отличным общим источником информации о dtrace).

0 голосов
/ 02 октября 2014

В linux самый надежный способ идентификации переключения контекста, который я нашел, - это команда:

pidstat -hluwrt  | grep "processname"

Столбец 'tid' (# 3) аналогичен столбцу 'gettid ()', что позволяет разработчику напрямую сопоставлять, какой поток использует ЦП и переключение контекста. Я предлагаю, чтобы при создании потока для программы выплевывалось значение gettid (): printf ("% lul", gettid ()) .

Последние 2 столбца, предшествующие командной строке процесса, - это число переключений контекста 'cswtch / s' (добровольное) и 'nvcswtch / s' (недобровольное) в секунду.

Когда значение «cswtch / s» высокое (1000), ваш процесс чрезмерно циклически повторяет «пробуждение» и «сон». Возможно, вы захотите использовать какой-нибудь буфер для потоков, что позволит увеличить время пробуждения и сна. пример: когда буфер НЕ заполнен, поток дольше остается в спящем режиме. Когда буфер заполняется, поток не активен, пока буфер не станет пустым.

Когда значение nvswtch / s высокое (1000), это признак того, что ваша система сильно загружена, и отдельный поток конкурирует за процессорное время. Возможно, вы захотите выяснить нагрузку на сервер, количество активных процессов и потоков на сервере: «top» или «htop» - ваши друзья.

Я считаю следующий скрипт полезным для отладки / оптимизации потоков процессов (выводится каждые 20 секунд):

stdbuf -oL pidstat -hluwrt  20 | stdbuf -oL grep -e "processname" -e "^#"

Документация для gettid: (документ здесь)
Документация для пидстата: (документ здесь)
Документация для stdbuf: (документ здесь)

...