Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.71/84: Рейтинг темы: голосов - 84, средняя оценка - 4.71
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
1

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

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

Author24 — интернет-сервис помощи студентам
Да, как?
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
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
27.12.2011, 10:51
Ответы с готовыми решениями:

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

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

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

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

77
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
21.07.2015, 15:18 61
Author24 — интернет-сервис помощи студентам
pthread к компилятору отношение не имеет! Если вы почитаете про POSIX, то MinGW там нет.
0
0 / 0 / 0
Регистрация: 21.07.2015
Сообщений: 4
21.07.2015, 17:02 62
У меня в голове полная каша. Не понимаю, зачем тогда нужен 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 63
Цитата Сообщение от xtier Посмотреть сообщение
Не понимаю, зачем тогда нужен MinGW, если такая базовая вещь как треды не работает.
До С11/С++11 в компиляторах не было потоков вообще!

Цитата Сообщение от xtier Посмотреть сообщение
Можно же сделать для винды posix api, обернув это все в winapi - пишем pthread_create(), а внутри CreateThread().
Есть Cygwin
1
18842 / 9841 / 2409
Регистрация: 30.01.2014
Сообщений: 17,284
21.07.2015, 20:06 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.
2
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
21.07.2015, 21:42  [ТС] 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++", глава "Завершение потоков" Хьюзов, если надо, я тебе скину.
1
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
21.07.2015, 21:58 66
Цитата Сообщение от kravam Посмотреть сообщение
На этом всё. Если парни из pthread считают уникальность потока в пределах приложения более, чем достаточной- это их право. А вот интересно, как в линуксе идентифицируют потоки в пределах оси?
В ядре поток и процесс - одна сущность. Но я не понимаю зачем идентифицировать потоки за пределами процесса? В пределах процесса - пожалуйста, а пределами зачем?
0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
21.07.2015, 22:12  [ТС] 67
Цитата Сообщение от castorsky Посмотреть сообщение
В ядре поток и процесс - одна сущность. Но я не понимаю зачем идентифицировать потоки за пределами процесса? В пределах процесса - пожалуйста, а пределами зачем?
чтобы понять это, нужно полюбить винду...
0
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
21.07.2015, 22:16 68
kravam, житейский пример, если не сложно. Первое впечатление - это разрушает безопасноть.
1
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
21.07.2015, 22:26  [ТС] 69
Цитата Сообщение от castorsky Посмотреть сообщение
kravam, житейский пример, если не сложно. Первое впечатление - это разрушает безопасноть.
Естеесно, я собираюсь залезать своими толстыми пальцами в чужие приложения и не скрываю это. У меня вот, например в планах, копировать текст в окне, который часто меняется (стороннее web-приложение). Как скопировать его безошибочно? Вот, допустим, я вижу "Маня Ваня", хоп, программно посылаю окну нужные сообщения, потом читаю скопированный текст, а он "МаняВаня", без пробела. Каких-то моментов хватало, чтобы текст чуть-чуть изменился. Мне с ним как работать-то с искажённым текстом? А мне его программно нужно обрабатывать! Исходников приложения у меня нет. Остаётся один выход- замораживать все потоки того приложения, кроме оконного и посылать окну программно соответствующие сообщения. А чтобы заморозить их потоки, нужно знать их TIDы в пределах оси. Это я не сейчас такую задачу придумал, давно уже она у меня была, не знал просто, ка решить, не догадался, что потоки нужно убивать, а потом только текст копировать.
0
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
21.07.2015, 22:31 70
Т.е. дальнейшая работа приложения не предусмотрена? Вы же потоки убиваете, значит программа уже не работает корректно.
0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
21.07.2015, 22:33  [ТС] 71
Цитата Сообщение от castorsky Посмотреть сообщение
Т.е. дальнейшая работа приложения не предусмотрена? Вы же потоки убиваете, значит программа уже не работает корректно
Замораживаю потоки- скопировал текст- размораживаю потоки, это же возможно.
0
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
21.07.2015, 22:41 72
Понятно, pthread_kill, SIGSTOP/SIGCONT. Осталось только заставить целевую программу выполнять это по требованию. Это конечно же хак и не удивляйтесь что система не предоставляет подобных возможностей.
0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
21.07.2015, 22:53  [ТС] 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() есть, то для чего-то же она есть! Хотя, тут и за меньшее пытались наказать! Но пришёл строгий но справедливый супер-модератор и раздал всем сёстрам по серьгам.
0
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
21.07.2015, 23:04 74

Не по теме:

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


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

Не по теме:

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

0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
21.07.2015, 23:20  [ТС] 77
Но это не значит, что всё хорошо! Не забываем, что чтобы обработать сообщение, оконный поток должен работать. Но мы помним, что текст в окне перерисовывается часто. Если частота перерисовки зависит исключительно от главного потока, который, напоминаю, работает во время отправки сообщений и, возможно перерисовывает текст- тогда бесполезно копировать текст- всё равно будут ошибки. Если за обновление данных отвечают другие потоки (которые я замораживаю), тогда может получиться.
0
бжни
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
26.07.2015, 20:01 78
я не понимаю о чем плачь, но если очень хочется..
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
26.07.2015, 20:01
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.07.2015, 20:01
Помогаю со студенческими работами здесь

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

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

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

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

как получить дескриптор файла, открытый функцией fopen
как получить дескриптор файла, открытый функцией fopen

Как можно программно открыть ссылку и получить в окне броузера открытый файл?
Добрый день! Как можно программно открыть ссылку и получить в окне броузера открытый файл? ...


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

Или воспользуйтесь поиском по форуму:
78
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru