Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.57/98: Рейтинг темы: голосов - 98, средняя оценка - 4.57
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705

Как получить TID текущего потока? (библиотека pthread, компилятор g++ 4.6.1 открытый вопрос niXmanу)

27.12.2011, 10:51. Показов 20186. Ответов 77
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Да, как?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <windows.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
 
void *BusyWork(void *t) {
   printf("TID= %x\n", pthread_self());
   printf("TID= %x\n", (unsigned int)GetCurrentThreadId ());
   return NULL;
}
 
int main () {
 pthread_t thread;
 pthread_create(&thread, NULL, BusyWork, NULL); 
 getchar ();
}
ВЫвод:
C++
1
2
TID= 1
TID= df0
Компилятор g++, версия 4.6.1, сборка niXmana, pthread_t определён как:
C++
1
2
typedef unsigned int uintptr_t;
typedef uintptr_t pthread_t;
//////////////////////////////////////////////////////////////////////////////////////////////////

Меж тем других версия g++, в частности, 4.5.0, pthread_t был определён так:

C++
1
2
3
4
5
6
typedef struct {
    void * p;                   /* Pointer to actual object */
    unsigned int x;             /* Extra information - reuse count etc */
} ptw32_handle_t;
 
typedef ptw32_handle_t pthread_t;

ПОлучение TID потока, сводилось таким обраом, к:
C++
1
2
3
   pthread_t pthread_t_ = pthread_self();
unsigned int TID= *(unsigned int*)(pthread_t_.p);
   printf("TID= %x\n", (unsigned int)TID);
И всё было круто. Может мне кто-нибудь ответить, как используя pthread_self() компилятора 4.6.1 получить TID потока?

Добавлено через 17 часов 32 минуты
niXman, я сделал так, открыл \i686-pc-mingw32\include, заккоментил
C++
1
//pthread_t WINPTHREAD_API pthread_self(void);
написал:
C++
1
2
#include <windows.h>
#define pthread_self (pthread_t)GetCurrentThreadId
Код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
 
void *BusyWork(void *t) {
   pthread_t pthread_t_= pthread_self();
   printf("TID= %x\n", pthread_t_);
   printf("TID= %x\n", pthread_self());
   printf("TID= %x\n", (unsigned int)GetCurrentThreadId ());
   return NULL;
}
 
int main () {
 pthread_t thread;
 pthread_create(&thread, NULL, BusyWork, NULL); 
 getchar ();
}

ВЫвод:
Bash
1
2
3
TID= be0
TID= be0
TID= be0
Но хотелось бы всё-таки услышать мнение знающих людей, а то какие ещё сюрпризы меня поджидают?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
27.12.2011, 10:51
Ответы с готовыми решениями:

Как узнать, что поток закончился (библиотека pthread)?
Друзья! Есть ли какая-нибудь pthread-функция, которая вызывается в основном потоке X и показывает- да, созданный ранее поток Y закончился? ...

Компилятор не видит библиотеку pthread
При реализации многопоточности столкнулся с проблемой :компилятор не видит библиотеку libpthread,позже выяснил что на компе вообще нет...

Приоритет потока (pthread)
Доброго времени суток! Есть такой код:#include &lt;pthread.h&gt; #include &lt;iostream&gt; #include &lt;stdlib.h&gt; #include &lt;unistd.h&gt; ...

77
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
21.07.2015, 15:18
Студворк — интернет-сервис помощи студентам
pthread к компилятору отношение не имеет! Если вы почитаете про POSIX, то MinGW там нет.
0
0 / 0 / 0
Регистрация: 21.07.2015
Сообщений: 4
21.07.2015, 17:02
У меня в голове полная каша. Не понимаю, зачем тогда нужен MinGW, если такая базовая вещь как треды не работает. Можно же сделать для винды posix api, обернув это все в winapi - пишем pthread_create(), а внутри CreateThread(). А здесь какая-то реализация своя и еще не работающая. В чем смысл?

И чтобы два раза не вставать. Это зачем они так пишут:
pthread_create(&drawer, nil, (void *(*)(void *)) drawProgress, &arg);
ведь исправно работает &drawProgress, может, какие-то исторические причины и раньше нельзя было так?
и как читать такую конструкцию (void *(*)(void *)) drawProgress ?

Спасибо!
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
21.07.2015, 17:21
Цитата Сообщение от xtier Посмотреть сообщение
Не понимаю, зачем тогда нужен MinGW, если такая базовая вещь как треды не работает.
До С11/С++11 в компиляторах не было потоков вообще!

Цитата Сообщение от xtier Посмотреть сообщение
Можно же сделать для винды posix api, обернув это все в winapi - пишем pthread_create(), а внутри CreateThread().
Есть Cygwin
1
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
21.07.2015, 20:06
Цитата Сообщение от xtier Посмотреть сообщение
pthread_create(&drawer, nil, (void *(*)(void *)) drawProgress, &arg);
ведь исправно работает &drawProgress, может, какие-то исторические причины и раньше нельзя было так?
Это так пишут для С++, т.к. там более строгая типизация. В С работает без явного приведения (но приведение все равно есть - только неявное!)
Цитата Сообщение от xtier Посмотреть сообщение
и как читать такую конструкцию (void *(*)(void *)) drawProgress ?
Это приведение типа указателя на функцию. Прототип для коллбэка, который принимает pthread_create такой -
C++
1
void * func(void *argument)
а в твоем коде передается
C++
1
void func(void *argument)
Поэтому в С++ необходимо приведение, т.к. прототипы не совпадают.

Цитата Сообщение от xtier Посмотреть сообщение
Не понимаю, зачем тогда нужен MinGW, если такая базовая вещь как треды не работает.
winpthread вообще. никакого. отношения. к mingw не имеет. Это сторонняя библиотека, которую, некоторые мейнтейнеры изволят включать в свою сборку mingw. Это их личное дело. Делается это, чтобы получить большее количество *nix приложений, работающих под виндой. К слову, конструкция
C++
1
pthread_cancel(pthread_self());
в твоих примерах не нужна чуть меньше, чем полностью, т.к. там достаточно обычного return. Корректно написанный код с использованием pthread (без хаков и т.п.) будет жить и под winpthread без всяких проблем.

Добавлено через 4 минуты
Цитата Сообщение от xtier Посмотреть сообщение
пишем pthread_create(), а внутри CreateThread()
Оно так и сделано. А кэнселить потоки все равно очень плохой стиль, вот видимо автор и не стал этим заморачиваться. В любом случае, она не входит в официальную поставку mingw. С офф. сайта:
Pthreads is part of POSIX and Windows isn't a POSIX system. However, there is a third party library on sourceware.org named pthreads-win32. Sourceware.org provides its own lists and MinGW does not support it but you are free to use it with MinGW at your own risk.
2
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
21.07.2015, 21:42  [ТС]
Цитата Сообщение от xtier Посмотреть сообщение
Автор, удалось выяснить в чем проблема?
Да ни в чём. Год назад отписался:
Цитата Сообщение от kravam Посмотреть сообщение
Вынужден признать, что на некотором отрезке времени мне в моих многопоточных программах вполне хватало TIDa, возвращённого pthread_self().
На этом всё. Если парни из pthread считают уникальность потока в пределах приложения более, чем достаточной- это их право. А вот интересно, как в линуксе идентифицируют потоки в пределах оси?

++++++++++++++++++++++++++++++++++++++++ ++++++

Поток должен самоубиваться pthread_exit();

++++++++++++++++++++++++++++++++++++++++ ++++++

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

pthread_setcancelstate() и pthread_setcanceltype ();

Вот полностью код (кстати, необязательно создавать в твоём примере два потока, это вносит лишнюю путаницу):

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <windows.h>
 
 
#define nil NULL
 
typedef struct {
    size_t progress;
    int errorCode;
} ThreadArg;
 
void drawProgress(void *arg) {
 
 int OldState,OldType; 
 
 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &OldState); 
 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS,&OldType); 
 
 
    ThreadArg* argument = (ThreadArg*)arg;
    argument->progress = 99;
    while(argument->progress < 100) {
        Sleep(100);
        argument->progress--;
        printf("Progress %lu \n", argument->progress);
        if(argument->progress == 7) {
            pthread_cancel(pthread_self());
        }
    }
}
 
 
 
int main(int argc, const char *argv[]) {
    pthread_t drawer, loader;
    ThreadArg arg;
    pthread_create(&drawer, nil, (void *(*)(void *)) drawProgress, &arg);
    pthread_join(drawer, nil);
    return 0;
}
Подробнее в книге "Параллельное_и_распределённое_программи рование_с_использованием_C++", глава "Завершение потоков" Хьюзов, если надо, я тебе скину.
1
 Аватар для castorsky
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
21.07.2015, 21:58
Цитата Сообщение от kravam Посмотреть сообщение
На этом всё. Если парни из pthread считают уникальность потока в пределах приложения более, чем достаточной- это их право. А вот интересно, как в линуксе идентифицируют потоки в пределах оси?
В ядре поток и процесс - одна сущность. Но я не понимаю зачем идентифицировать потоки за пределами процесса? В пределах процесса - пожалуйста, а пределами зачем?
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
21.07.2015, 22:12  [ТС]
Цитата Сообщение от castorsky Посмотреть сообщение
В ядре поток и процесс - одна сущность. Но я не понимаю зачем идентифицировать потоки за пределами процесса? В пределах процесса - пожалуйста, а пределами зачем?
чтобы понять это, нужно полюбить винду...
0
 Аватар для castorsky
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
21.07.2015, 22:16
kravam, житейский пример, если не сложно. Первое впечатление - это разрушает безопасноть.
1
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
21.07.2015, 22:26  [ТС]
Цитата Сообщение от castorsky Посмотреть сообщение
kravam, житейский пример, если не сложно. Первое впечатление - это разрушает безопасноть.
Естеесно, я собираюсь залезать своими толстыми пальцами в чужие приложения и не скрываю это. У меня вот, например в планах, копировать текст в окне, который часто меняется (стороннее web-приложение). Как скопировать его безошибочно? Вот, допустим, я вижу "Маня Ваня", хоп, программно посылаю окну нужные сообщения, потом читаю скопированный текст, а он "МаняВаня", без пробела. Каких-то моментов хватало, чтобы текст чуть-чуть изменился. Мне с ним как работать-то с искажённым текстом? А мне его программно нужно обрабатывать! Исходников приложения у меня нет. Остаётся один выход- замораживать все потоки того приложения, кроме оконного и посылать окну программно соответствующие сообщения. А чтобы заморозить их потоки, нужно знать их TIDы в пределах оси. Это я не сейчас такую задачу придумал, давно уже она у меня была, не знал просто, ка решить, не догадался, что потоки нужно убивать, а потом только текст копировать.
0
 Аватар для castorsky
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
21.07.2015, 22:31
Т.е. дальнейшая работа приложения не предусмотрена? Вы же потоки убиваете, значит программа уже не работает корректно.
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
21.07.2015, 22:33  [ТС]
Цитата Сообщение от castorsky Посмотреть сообщение
Т.е. дальнейшая работа приложения не предусмотрена? Вы же потоки убиваете, значит программа уже не работает корректно
Замораживаю потоки- скопировал текст- размораживаю потоки, это же возможно.
0
 Аватар для castorsky
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
21.07.2015, 22:41
Понятно, pthread_kill, SIGSTOP/SIGCONT. Осталось только заставить целевую программу выполнять это по требованию. Это конечно же хак и не удивляйтесь что система не предоставляет подобных возможностей.
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
21.07.2015, 22:53  [ТС]
Не стоит так драматизировать. Тривиальнейшая задача.

Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <stdio.h>
#define _WIN32_WINNT 0X501
#include <windows.h>
#include <tlhelp32.h>
#include <WINBASE.H>
#include <Winnt.h> 
 
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 
VOID SuspendProcess(DWORD dwProcessID)    {
 
 // получаем список потоков в процессе
 HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwProcessID);
 
 if (hSnapshot != INVALID_HANDLE_VALUE) {
 
  //Это прежде чем передавать &te в качестве параметра
  //Опеределяем её размер
  THREADENTRY32 te;
  te.dwSize =  sizeof(te) ;
 
  //Это мы типа проверяем, есть ли первичный поток 
  BOOL fOk = Thread32First(hSnapshot, &te);
 
  // просматриваем список потоков
  //функция Thread32Next не остановится, пока не пробежится по ВСЕМ потокам в системе.
  //Это написано здесь
  //http://progeru.narod.ru/article/cpp_proc.html
  for (;fOk; fOk = Thread32Next(hSnapshot, &te)) {
 
   // относится ли данный поток к нужному процессу
   if (te.th32OwnerProcessID == dwProcessID) {
 
    // пытаемся получить описатель потока по его идентификатору
    HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, te.th32ThreadID);
 
    if (hThread != NULL)    {
 
    // приоcтанавливаем поток
      SuspendThread(hThread);
     CloseHandle(hThread);
    }
 
   }
  }
  CloseHandle(hSnapshot);
 }
} 
 
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
int main () {
 
 SetConsoleCP(1251);
 SetConsoleOutputCP(1251);
 
 
 int PIDprocessa;
 printf ("Вводи PID процесса\n");
 scanf ("%d", &PIDprocessa);
 
 
 SuspendProcess (PIDprocessa);
 return 0;
}


Меня даже привлечь не могут к ответственности на этом форуме - если SuspendThread() есть, то для чего-то же она есть! Хотя, тут и за меньшее пытались наказать! Но пришёл строгий но справедливый супер-модератор и раздал всем сёстрам по серьгам.
0
 Аватар для castorsky
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
21.07.2015, 23:04

Не по теме:

Я вроде ничего не драматизировал


Ну а данные Вы извлекаете из страниц или инициируете сброс в память.
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
21.07.2015, 23:11  [ТС]
Цитата Сообщение от castorsky Посмотреть сообщение
Ну а данные Вы извлекаете из страниц или инициируете сброс в память.
Это вопрос был? Данные я извлекаю из окна. То есть посылаю ему программно сообщение а-ля Ctrl+A- это выделяется весь текст. Потом другое сообщение Ctrl+Insert- всё, текст в буфере обмена, а потом можно и потоки разморозить.
1
21.07.2015, 23:14

Не по теме:

Да, забыл знак вопроса. Спасибо.

0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
21.07.2015, 23:20  [ТС]
Но это не значит, что всё хорошо! Не забываем, что чтобы обработать сообщение, оконный поток должен работать. Но мы помним, что текст в окне перерисовывается часто. Если частота перерисовки зависит исключительно от главного потока, который, напоминаю, работает во время отправки сообщений и, возможно перерисовывает текст- тогда бесполезно копировать текст- всё равно будут ошибки. Если за обновление данных отвечают другие потоки (которые я замораживаю), тогда может получиться.
0
бжни
 Аватар для alex_x_x
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
26.07.2015, 20:01
я не понимаю о чем плачь, но если очень хочется..
https://code.google.com/p/libp... 9dea2a63c4

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
{
    arch_thread_info *pv = (arch_thread_info *) HeapAlloc(libpthread_heap, HEAP_ZERO_MEMORY, sizeof(arch_thread_info));
    if (pv == NULL)
        return set_errno(ENOMEM);
 
    /* TODO: use attr (StackSize)to create thread */
    pv->arg = arg;
    pv->worker = start_routine;
    pv->state = PTHREAD_CREATE_JOINABLE;
    pv->handle = (HANDLE) _beginthreadex(NULL, 0, worker_proxy, pv, CREATE_SUSPENDED, NULL);
 
    if (pv->handle == INVALID_HANDLE_VALUE) {
        HeapFree(libpthread_heap, 0, pv);
        return errno;
    }
 
    /* TODO: SetThreadPriority */
 
    if ((pv->state & PTHREAD_CREATE_DETACHED) != 0)
      CloseHandle(pv->handle);
 
    ResumeThread(pv->handle);
    *thread = (pthread_t) pv;
    return 0;
}
итого на винде pthread_create - обертка над _beginthreadex (что логично)
под pthread_t на самом деле кроется arch_thread_info, в котором есть член handle.
из него можно уже получить TID через GetThreadId

какой в этом смысл, зм?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
26.07.2015, 20:01

библиотека pthread.h в Code::Blocks
не могу найти как подключить библиотеку pthread.h в Code::Blocks. Помогите,пожалуйста, кто знает.

Pthread функция потока внутри класса
Нужно чтобы функция pthread_create принимала на входе функцию-член класса, в котором я вызываю pthread_create собственно. Так сделать не...

Изолирование данных родительского потока от дочернего в pthread
Сабж. Как сделать так, что бы в дочернем потоке не были видны данные родительского потока? Для создания потока использую...

Параллельное программирование, библиотека pthread. Объединение, пересечение, разность множеств A, B, C
Приветствую всех! Возникла проблема, ума не приложу как ниже указанную задачу реализовать через библиотеку pthread. Форумчане, хелпаните...

Как получить ответ на открытый порт UDP
Доброго времени суток! Делаю небольшую программку которая отправляет широковещательный запрос на 239.255.255.250:1900 Требуется...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
78
Ответ Создать тему
Новые блоги и статьи
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru