Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 66, средняя оценка - 4.89
kravam
быдлокодер
1691 / 878 / 44
Регистрация: 04.06.2008
Сообщений: 5,411
#1

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

27.12.2011, 10:51. Просмотров 8530. Ответов 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
Но хотелось бы всё-таки услышать мнение знающих людей, а то какие ещё сюрпризы меня поджидают?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.12.2011, 10:51     Как получить TID текущего потока? (библиотека pthread, компилятор g++ 4.6.1 открытый вопрос niXmanу)
Посмотрите здесь:
Как узнать, что поток закончился (библиотека pthread)? C++
C++ Linux Приоритет потока (pthread)
библиотека pthread.h в Code::Blocks C++
C++ Pthread функция потока внутри класса
C++ как получить дескриптор файла, открытый функцией fopen
C++ WinAPI HINSTENCE из текущего потока
Как получить имя текущего пользователя Windows? C++ WinAPI
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Dmitriy_M
1340 / 1221 / 111
Регистрация: 20.03.2009
Сообщений: 4,374
Записей в блоге: 11
21.07.2015, 15:18     Как получить TID текущего потока? (библиотека pthread, компилятор g++ 4.6.1 открытый вопрос niXmanу) #61
pthread к компилятору отношение не имеет! Если вы почитаете про POSIX, то MinGW там нет.
xtier
0 / 0 / 0
Регистрация: 21.07.2015
Сообщений: 4
21.07.2015, 17:02     Как получить TID текущего потока? (библиотека pthread, компилятор g++ 4.6.1 открытый вопрос niXmanу) #62
У меня в голове полная каша. Не понимаю, зачем тогда нужен MinGW, если такая базовая вещь как треды не работает. Можно же сделать для винды posix api, обернув это все в winapi - пишем pthread_create(), а внутри CreateThread(). А здесь какая-то реализация своя и еще не работающая. В чем смысл?

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

Спасибо!
Dmitriy_M
1340 / 1221 / 111
Регистрация: 20.03.2009
Сообщений: 4,374
Записей в блоге: 11
21.07.2015, 17:21     Как получить TID текущего потока? (библиотека pthread, компилятор g++ 4.6.1 открытый вопрос niXmanу) #63
Цитата Сообщение от xtier Посмотреть сообщение
Не понимаю, зачем тогда нужен MinGW, если такая базовая вещь как треды не работает.
До С11/С++11 в компиляторах не было потоков вообще!

Цитата Сообщение от xtier Посмотреть сообщение
Можно же сделать для винды posix api, обернув это все в winapi - пишем pthread_create(), а внутри CreateThread().
Есть Cygwin
DrOffset
6909 / 4102 / 933
Регистрация: 30.01.2014
Сообщений: 6,896
21.07.2015, 20:06     Как получить TID текущего потока? (библиотека pthread, компилятор g++ 4.6.1 открытый вопрос niXmanу) #64
Цитата Сообщение от 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.
kravam
быдлокодер
1691 / 878 / 44
Регистрация: 04.06.2008
Сообщений: 5,411
21.07.2015, 21:42  [ТС]     Как получить TID текущего потока? (библиотека pthread, компилятор g++ 4.6.1 открытый вопрос niXmanу) #65
Цитата Сообщение от 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++", глава "Завершение потоков" Хьюзов, если надо, я тебе скину.
castorsky
1950 / 1040 / 78
Регистрация: 29.11.2013
Сообщений: 3,262
21.07.2015, 21:58     Как получить TID текущего потока? (библиотека pthread, компилятор g++ 4.6.1 открытый вопрос niXmanу) #66
Цитата Сообщение от kravam Посмотреть сообщение
На этом всё. Если парни из pthread считают уникальность потока в пределах приложения более, чем достаточной- это их право. А вот интересно, как в линуксе идентифицируют потоки в пределах оси?
В ядре поток и процесс - одна сущность. Но я не понимаю зачем идентифицировать потоки за пределами процесса? В пределах процесса - пожалуйста, а пределами зачем?
kravam
быдлокодер
1691 / 878 / 44
Регистрация: 04.06.2008
Сообщений: 5,411
21.07.2015, 22:12  [ТС]     Как получить TID текущего потока? (библиотека pthread, компилятор g++ 4.6.1 открытый вопрос niXmanу) #67
Цитата Сообщение от castorsky Посмотреть сообщение
В ядре поток и процесс - одна сущность. Но я не понимаю зачем идентифицировать потоки за пределами процесса? В пределах процесса - пожалуйста, а пределами зачем?
чтобы понять это, нужно полюбить винду...
castorsky
1950 / 1040 / 78
Регистрация: 29.11.2013
Сообщений: 3,262
21.07.2015, 22:16     Как получить TID текущего потока? (библиотека pthread, компилятор g++ 4.6.1 открытый вопрос niXmanу) #68
kravam, житейский пример, если не сложно. Первое впечатление - это разрушает безопасноть.
kravam
быдлокодер
1691 / 878 / 44
Регистрация: 04.06.2008
Сообщений: 5,411
21.07.2015, 22:26  [ТС]     Как получить TID текущего потока? (библиотека pthread, компилятор g++ 4.6.1 открытый вопрос niXmanу) #69
Цитата Сообщение от castorsky Посмотреть сообщение
kravam, житейский пример, если не сложно. Первое впечатление - это разрушает безопасноть.
Естеесно, я собираюсь залезать своими толстыми пальцами в чужие приложения и не скрываю это. У меня вот, например в планах, копировать текст в окне, который часто меняется (стороннее web-приложение). Как скопировать его безошибочно? Вот, допустим, я вижу "Маня Ваня", хоп, программно посылаю окну нужные сообщения, потом читаю скопированный текст, а он "МаняВаня", без пробела. Каких-то моментов хватало, чтобы текст чуть-чуть изменился. Мне с ним как работать-то с искажённым текстом? А мне его программно нужно обрабатывать! Исходников приложения у меня нет. Остаётся один выход- замораживать все потоки того приложения, кроме оконного и посылать окну программно соответствующие сообщения. А чтобы заморозить их потоки, нужно знать их TIDы в пределах оси. Это я не сейчас такую задачу придумал, давно уже она у меня была, не знал просто, ка решить, не догадался, что потоки нужно убивать, а потом только текст копировать.
castorsky
1950 / 1040 / 78
Регистрация: 29.11.2013
Сообщений: 3,262
21.07.2015, 22:31     Как получить TID текущего потока? (библиотека pthread, компилятор g++ 4.6.1 открытый вопрос niXmanу) #70
Т.е. дальнейшая работа приложения не предусмотрена? Вы же потоки убиваете, значит программа уже не работает корректно.
kravam
быдлокодер
1691 / 878 / 44
Регистрация: 04.06.2008
Сообщений: 5,411
21.07.2015, 22:33  [ТС]     Как получить TID текущего потока? (библиотека pthread, компилятор g++ 4.6.1 открытый вопрос niXmanу) #71
Цитата Сообщение от castorsky Посмотреть сообщение
Т.е. дальнейшая работа приложения не предусмотрена? Вы же потоки убиваете, значит программа уже не работает корректно
Замораживаю потоки- скопировал текст- размораживаю потоки, это же возможно.
castorsky
1950 / 1040 / 78
Регистрация: 29.11.2013
Сообщений: 3,262
21.07.2015, 22:41     Как получить TID текущего потока? (библиотека pthread, компилятор g++ 4.6.1 открытый вопрос niXmanу) #72
Понятно, pthread_kill, SIGSTOP/SIGCONT. Осталось только заставить целевую программу выполнять это по требованию. Это конечно же хак и не удивляйтесь что система не предоставляет подобных возможностей.
kravam
быдлокодер
1691 / 878 / 44
Регистрация: 04.06.2008
Сообщений: 5,411
21.07.2015, 22:53  [ТС]     Как получить TID текущего потока? (библиотека pthread, компилятор g++ 4.6.1 открытый вопрос niXmanу) #73
Не стоит так драматизировать. Тривиальнейшая задача.

Кликните здесь для просмотра всего текста
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() есть, то для чего-то же она есть! Хотя, тут и за меньшее пытались наказать! Но пришёл строгий но справедливый супер-модератор и раздал всем сёстрам по серьгам.
castorsky
1950 / 1040 / 78
Регистрация: 29.11.2013
Сообщений: 3,262
21.07.2015, 23:04     Как получить TID текущего потока? (библиотека pthread, компилятор g++ 4.6.1 открытый вопрос niXmanу) #74

Не по теме:

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


Ну а данные Вы извлекаете из страниц или инициируете сброс в память.
kravam
быдлокодер
1691 / 878 / 44
Регистрация: 04.06.2008
Сообщений: 5,411
21.07.2015, 23:11  [ТС]     Как получить TID текущего потока? (библиотека pthread, компилятор g++ 4.6.1 открытый вопрос niXmanу) #75
Цитата Сообщение от castorsky Посмотреть сообщение
Ну а данные Вы извлекаете из страниц или инициируете сброс в память.
Это вопрос был? Данные я извлекаю из окна. То есть посылаю ему программно сообщение а-ля Ctrl+A- это выделяется весь текст. Потом другое сообщение Ctrl+Insert- всё, текст в буфере обмена, а потом можно и потоки разморозить.
castorsky
21.07.2015, 23:14
  #76

Не по теме:

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

kravam
быдлокодер
1691 / 878 / 44
Регистрация: 04.06.2008
Сообщений: 5,411
21.07.2015, 23:20  [ТС]     Как получить TID текущего потока? (библиотека pthread, компилятор g++ 4.6.1 открытый вопрос niXmanу) #77
Но это не значит, что всё хорошо! Не забываем, что чтобы обработать сообщение, оконный поток должен работать. Но мы помним, что текст в окне перерисовывается часто. Если частота перерисовки зависит исключительно от главного потока, который, напоминаю, работает во время отправки сообщений и, возможно перерисовывает текст- тогда бесполезно копировать текст- всё равно будут ошибки. Если за обновление данных отвечают другие потоки (которые я замораживаю), тогда может получиться.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.07.2015, 20:01     Как получить TID текущего потока? (библиотека pthread, компилятор g++ 4.6.1 открытый вопрос niXmanу)
Еще ссылки по теме:
C++ Builder Как получить имя текущего пользователя в Win2000 ?
C++ вытянуть значение HINSTENCE из текущего потока
Как получить адрес текущего окна зная его Хендл C++ WinAPI
Получить открытый текст C++
Компилятор MinGW в NetBeans не видит класс потока (thread) C++

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

Или воспользуйтесь поиском по форуму:
alex_x_x
бжни
2445 / 1650 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
26.07.2015, 20:01     Как получить TID текущего потока? (библиотека pthread, компилятор g++ 4.6.1 открытый вопрос niXmanу) #78
я не понимаю о чем плачь, но если очень хочется..
https://code.google.com/p/libpthread...5a9e9dea2a63c4

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

какой в этом смысл, зм?
Yandex
Объявления
26.07.2015, 20:01     Как получить TID текущего потока? (библиотека pthread, компилятор g++ 4.6.1 открытый вопрос niXmanу)
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru