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

предлагаю людям класс "каждому потоку- своё окно" для тестирования многопоточных приложений. - C++

Войти
Регистрация
Восстановить пароль
 
kravam
быдлокодер
 Аватар для kravam
1513 / 873 / 44
Регистрация: 04.06.2008
Сообщений: 5,302
09.11.2011, 16:37     предлагаю людям класс "каждому потоку- своё окно" для тестирования многопоточных приложений. #1
Друзья! То есть если вы разрабатывает многопоточные приложения и закалебались смотреть, что тот или иной поток выводит, то этот класс для вас. Использовать его просто. Подключаете хидер и пишете:
C++
1
cout__<< "что-то";
и видите, что появилось окно, глде написано "что-то"
Если создадите ДРУГОЙ поток и напишите там:
C++
1
cout__<< "еще что-то";
То и увидите другое окно с еще чем-то.
Вот так и тестируйте на здоровье, каждый поток будет в своё окно выводить чё вам надо.

Там есть и недостаток- по закрытию какого-нибудь окна, поток, пишущий в него не закрывается. Другое дело, что пишет он в никуда. Кому надо-пишите свои оконые функции для искоренения этого недостатка

По окнам: их количество и размеры определяются в маросах. Если представлять окна в виде матрицы, то вы увидите на экране матрицу из окон 3 на 4 окна
Количество столбцов в макросе опредлелено, количество строк не более 3-х, запрограммировано.
Поэкспеременируйте.

По умолчанию создаются 12 потоков и соответствено 12 окон, куда потоки пишут TIDы и компьютерное время.
Вся эта что-то распространяется по лицензии GPL.

Вот сам хидер:
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#ifndef MYCOUT___H
#define MYCOUT___H
 
 
#include <iostream> 
#include <pthread.h> 
#include <windows.h>
#include <stdio.h>
#include <map>
using namespace std;
                      /////////////////////////////////////
                      //это что-то определяет координаты окон
                      /////////////////////////////////////
                      //////////и их количество////////////
 
#define skolko_v_rad 4
#define x_levii_verhni_ugol 100
#define y_levii_verhni_ugol 100
#define shirina_okna 250
#define visota__okna 200
#define rasstoinie_mezhdu_oknami_po_gor 20
#define rasstoinie_mezhdu_oknami_po_ver 20
                           //количечство потоков-окон
#define kol_vo_potokov 12
                      /////////////////////////////////////
                      //это что-то определяет координаты окон
                      /////////////////////////////////////
 
 
 
 
//КОму надо кропайте свои оконные процедуры                     
//LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
 
 
pthread_mutex_t mutex= PTHREAD_MUTEX_INITIALIZER;
HWND hwnd [kol_vo_potokov];
//класс класс класс класс класс класс класс класс класс класс класс класс 
//класс класс класс класс класс класс класс класс класс класс класс класс 
//класс класс класс класс класс класс класс класс класс класс класс класс 
//класс класс класс класс класс класс класс класс класс класс класс класс 
class cout_ {
 public:
  cout_ () {chotchik_okon= 0;}
 ~cout_ () {}
 
  //главная функция, из-зак оторой вся эта бодяга затеяна
  ostream& operator<< (string);
 
 private:
 
  //Это вот что-то есть словарь, ключи- TIDi потоков-писаталей
  //значения- HWND окон                                     
  map <HANDLE, HWND> TIDi_i_okna;
 
  
  //Счётчик окон и функции, которые его инкременируют и возвращают,
  //зачем-то я их сделал дружественными                            
  int chotchik_okon;   
  friend int f_chotchik_okon (cout_& cout__){return cout__.chotchik_okon;}
  friend void in_chotchik_okon (cout_& cout__){++cout__.chotchik_okon;}
 
};
//класс класс класс класс класс класс класс класс класс класс класс класс 
//класс класс класс класс класс класс класс класс класс класс класс класс 
//класс класс класс класс класс класс класс класс класс класс класс класс 
//класс класс класс класс класс класс класс класс класс класс класс класс 
 
 
 
//Это будет функция потока, который создаёт окна.                             
//если выяснитс, что поток, которым мы собираемся чё-то писать, вообще впервые
//включился в эту бодягу, то необходимо создать для него окно.                
//за создание окна отвечает, опять, же- другой поток. НАзовём его X           
//причём, что интересно- этот X может создавать только одно окно              
//поскольку это необходимо делать в разные моменты времени, по мере надобости 
//ВЫвод: таких иксов может и должно быть много                                
//тупо: на каждый пишущий поток своё окно и свой поток, который это окно      
//создаст.                                                                    
//А вот его функция, она ничё не может возвернуть, поскольку кропает цикл     
//приёмки сообщений для окна                                                  
void* f_potoka_sozd_okna (void*);
 
                             //реализация
              //реализацияреализацияреализацияреализация
 
ostream& cout_::operator<< (string stroka) {                                  //
                                                                              //
  HANDLE TID_etogo_potoka= *(HANDLE*)(pthread_self().p);                      //
                                                                              //
                                                                              //
  //проверяем, а есть ли окно для этого потока?                               //
  //Допустим, такого окна нет, это значит, что поток впервые будет что-то     //
  //писать.                                                                   //
  //тогда надо такое окно создать                                             //
  //pthread_mutex_lock (&mutex);                                              //
  if (TIDi_i_okna.find(TID_etogo_potoka)== TIDi_i_okna.end()) {               //
                                                                              //
   //Окно должно создастья в другом потоке                                    //
   //Дело в том, что в один поток не может одновременно создавать окно и      //
   //что-то туда                                                              //
   //писать. Этот поток пишет в окно. Значит, создавать окно должен           //
   //ДРУГОЙ ПОТОК                                                             //
   //И нам понадобится HWND этого окна                                        //
   HWND* pHWND= new HWND;                                                     //
   *pHWND= 0;                                                                 //
   pthread_t thread_t_okna;                                                   //
   pthread_create(&thread_t_okna, NULL, f_potoka_sozd_okna, pHWND);           //
   //Всё, есть новый поток и окно для него.                                   //
   //Теперь надо всё это занести в TIDi_i_TIDi                                //
                                                                              //
   //Это важно, ибо дальнейшее что-то должно происходит тогда, когда окно уже   //
   //создано, то есть pHWND должно стать коррекнтым более или менее, хе-хе    //
   while (!(*pHWND));                                                         //
    TIDi_i_okna [TID_etogo_potoka]= *pHWND;                                   //
  }                                                                           //
                                                                              //
                    //ну вё, тут собсно записывание                           //
  char* temp= new char [stroka.size()+ 2];                                    //
  strcpy (temp, stroka.c_str());                                              //
  temp [stroka.size()]= 10;                                                   //
  temp [stroka.size()+ 1]= 0;                                                 //
  for (int j= 0; j< strlen (temp); j++) {                                     //
   SendMessage ((HWND)TIDi_i_okna [TID_etogo_potoka], WM_CHAR, temp [j], 1);  //
  }                                                                           //
  delete temp;                                                                              //
}                                                                             //
              //реализацияреализацияреализацияреализация
                             //реализация
           
 
 
                          //Создание объекта
                              cout_ cout__;
                          //Создание объекта
 
 
//создаём окно создаём окно создаём окно создаём окно создаём окно создаём окно 
void* f_potoka_sozd_okna (void* pHWND) {                                           
             
           //Для начала определим координаты окна и его размеры
           //ЭТО x и y -координата верехнего левого угла окна  
           int x, y;
           int temp= f_chotchik_okon (cout__);
           
           pthread_mutex_lock (&mutex); 
           if (f_chotchik_okon (cout__)< skolko_v_rad) {
            y= y_levii_verhni_ugol;  
            x= x_levii_verhni_ugol+  (shirina_okna+ \
               rasstoinie_mezhdu_oknami_po_gor)* \
               f_chotchik_okon (cout__);
            in_chotchik_okon (cout__);
           }   
           else if (f_chotchik_okon (cout__)< skolko_v_rad* 2) {
            y= y_levii_verhni_ugol+ visota__okna+ \
             rasstoinie_mezhdu_oknami_po_ver* (2- 1);
            x= x_levii_verhni_ugol;
            x= x_levii_verhni_ugol+  (shirina_okna+ \
               rasstoinie_mezhdu_oknami_po_gor)* \
               (f_chotchik_okon (cout__)- skolko_v_rad* (2- 1));
            in_chotchik_okon (cout__);
           }
           else if (f_chotchik_okon (cout__)< skolko_v_rad* 3) {
            y= y_levii_verhni_ugol+ (visota__okna+ \
               rasstoinie_mezhdu_oknami_po_ver)* (3- 1);
            x= x_levii_verhni_ugol;
            x= x_levii_verhni_ugol+  (shirina_okna+ \
               rasstoinie_mezhdu_oknami_po_gor)* \
               (f_chotchik_okon (cout__)- skolko_v_rad* (3- 1));
            in_chotchik_okon (cout__);
           }
 
           pthread_mutex_unlock (&mutex);
           //с координтами разобрались                                        //
                                                                              //
           MSG messages;                                                      //
           *(HWND*)pHWND  = CreateWindowEx (                                  //
           0,                                                                 //
           "Edit",                                                            //
           NULL,                                                              //
           WS_OVERLAPPEDWINDOW|ES_MULTILINE|WS_VSCROLL|ES_AUTOVSCROLL,        //
           //CW_USEDEFAULT,                                                   //
           x, y, shirina_okna, visota__okna,                                  //
           NULL,                                                              //
           NULL,                                                              //
           0,                                                                 //
           NULL                                                               //
           );                                                                 //
           ShowWindow (*(HWND*)pHWND, SW_SHOWDEFAULT);                        //
           UpdateWindow (*(HWND*)pHWND);                                      //
           //= hwnd;                                                          //
           temp= f_chotchik_okon (cout__);                                    //
                                                                              //
           while (GetMessage (&messages, NULL, 0, 0))    {                    //
            TranslateMessage(&messages);                                      //
            DispatchMessage(&messages);                                       //
           }                                                                  //
}                                                                             //
//создаём окно создаём окно создаём окно создаём окно создаём окно создаём окно 
//недостаток: при закрытии какого-нибудь окна поток, пишущий в это окно, не   //
//закрывается и он продолжает писать, но в никуда. Чтобы его закрыть по       //
//закрытию окна, пишите свои оконные функции                                  //
#endif
А вот пример как использовать:
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
#include <mycout__.h>
 
/////////////////////////////////////////////////////////////////////////////
//Это функция потока-писателя
void *task1 (void* po) { 
 
   //РАзберёмся с TIDами
   char buffer [256];
   pthread_t pthread_t_ = pthread_self();
   int TID= *(int*)(pthread_t_.p);
   itoa (TID, buffer, 16);
   int temp= strlen (buffer);
 
 
   time_t lt= time (NULL);
   
   while (1) { 
    Sleep (1000+ TID%1000);
    buffer [temp]= 0;
    lt = time(NULL);
    cout__<< string(strcat(strcat (buffer, "__"), ctime(&lt))) ;
   }
 
 
 return NULL;
} 
/////////////////////////////////////////////////////////////////////////////
 
 
int main(int argc, char *argv[]) { 
 SetConsoleCP (1251);
 SetConsoleOutputCP (1251);
 //Объявляем потоки
 pthread_t array_p [kol_vo_potokov];
 
 
 //создаём
 for (int i= 0; i< kol_vo_potokov; i++) {
  pthread_create(&array_p[i],NULL,task1, NULL); // Создаем  потоки. 
 }
 
 
 // Дополнительная обработка. 
 for (int i= 0; i< kol_vo_potokov; i++) {
  pthread_join(array_p[i],NULL); // Ожидание завершения 
 }
 getchar ();
 return (0) ; 
}
Тестируйте, результаты сюда, будем посмотреть. При комиляции ОБЯЗАТЕЛЬНО создавайте окно консоли, ибо только закрыв его, мы сожете убить поцесс. Ну или ещё какими-нибудь методами тпа ProcessExplorer, но ну его.

 Комментарий модератора 
В следующий раз вместе со "что-то" я выпишу еще и карточку.
Следите за речью
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.11.2011, 16:37     предлагаю людям класс "каждому потоку- своё окно" для тестирования многопоточных приложений.
Посмотрите здесь:

C++ класс для представления понятия "контроллер видеомагнитофона"
C++ предлагаю программу людям "альтернативное копирование файлов в проводнике"
C++ предлагаю людям класс "рекурсивный обход матрицы" для решения задач на такую тематику
Предлагаю людям как усовершенствовать IDE Dev-Cpp 4.9.9.2 C++
C++ Разработать класс для понятия "Генератор шума"
Предлагаю людям класс для написания специфических снимков системы C++
C++ Ввести класс для работы с объектом "рациональная дробь"
C++ Класс "Вектор", меню для демонстрации его возможностей
Класс "Дробь" для обработки обычных дробей C++
C++ Класс для работы с объектом "рациональная дробь"
C++ Класс "строка" для работы со строками произвольной длины
Найти исходники для книги "UNIX. Разработка сетевых приложений" C++

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
kravam
быдлокодер
 Аватар для kravam
1513 / 873 / 44
Регистрация: 04.06.2008
Сообщений: 5,302
08.02.2012, 18:01  [ТС]     предлагаю людям класс "каждому потоку- своё окно" для тестирования многопоточных приложений. #2
Улучшение теперь в создаваемое окно можно выводить и русскоязычный текст, чего раньше, к сожалению, не наблюдалось
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
#ifndef MYCOUT___H
#define MYCOUT___H
 
 
#include <iostream> 
#include <pthread.h> 
#include <windows.h>
#include <stdio.h>
#include <sstream>
#include <map>
using namespace std;
                      /////////////////////////////////////
                      //эта что-то определяет координаты окон
                      /////////////////////////////////////
                      //////////и их количество////////////
 
#define skolko_v_rad 4
#define x_levii_verhni_ugol 100
#define y_levii_verhni_ugol 100
#define shirina_okna 250
#define visota__okna 200
#define rasstoinie_mezhdu_oknami_po_gor 20
#define rasstoinie_mezhdu_oknami_po_ver 20
                           //количество потоков-окон
#define kol_vo_potokov 12
                      /////////////////////////////////////
                      //эта что-то определяет координаты окон
                      /////////////////////////////////////
 
 
 
 
//КОму надо кропайте свои оконные процедуры                     
//LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
 
//Это чтобы ни с чем не спутать было
pthread_mutex_t _m__utex_= PTHREAD_MUTEX_INITIALIZER;
HWND hwnd [kol_vo_potokov];
//класс класс класс класс класс класс класс класс класс класс класс класс 
//класс класс класс класс класс класс класс класс класс класс класс класс 
//класс класс класс класс класс класс класс класс класс класс класс класс 
//класс класс класс класс класс класс класс класс класс класс класс класс 
class cout_ {
 public:
  cout_ () {chotchik_okon= 0;}
 ~cout_ () {}
 
  //главная функция, из-за которой вся эта бодяга затеяна
  cout_ operator<< (string);
 
  //Будем работать также и с int!
  cout_ operator<< (int);
 
  
 
 private:
 
  //Эта вот что-то есть словарь, ключи- TIDi потоков-писаталей
  //значения- HWND окон                                     
  map <HANDLE, HWND> TIDi_i_okna;
 
  
  //Счётчик окон и функции, которые его инкременируют и возвращают,
  //зачем-то я их сделал дружественными                            
  int chotchik_okon;   
  friend int f_chotchik_okon (cout_& cout__){return cout__.chotchik_okon;}
  friend void in_chotchik_okon (cout_& cout__){++cout__.chotchik_okon;}
 
};
//класс класс класс класс класс класс класс класс класс класс класс класс 
//класс класс класс класс класс класс класс класс класс класс класс класс 
//класс класс класс класс класс класс класс класс класс класс класс класс 
//класс класс класс класс класс класс класс класс класс класс класс класс 
 
 
 
//Это будет функция потока, который создаёт окна.                             
//если выяснитс, что поток, которым мы собираемся чё-то писать, вообще впервые
//включился в эту бодягу, то необходимо создать для него окно.                
//за создание окна отвечает, опять, же- другой поток. НАзовём его X           
//причём, что интересно- этот X может создавать только одно окно              
//поскольку это необходимо делать в разные моменты времени, по мере надобости 
//ВЫвод: таких иксов может и должно быть много                                
//тупо: на каждый пишущий поток своё окно и свой поток, который это окно      
//создаст.                                                                    
//А вот его функция, она ничё не может возвернуть, поскольку кропает цикл     
//приёмки сообщений для окна                                                  
void* f_potoka_sozd_okna (void*);
                                    //
                                    //
                                    //
                                    //
 
                               //реализация
              //реализацияреализацияреализацияреализация
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
cout_ cout_::operator<< (string stroka) {                                  //
                                                                              //
  HANDLE TID_etogo_potoka= *(HANDLE*)(pthread_self().p);                      //
                                                                              //
                                                                              //
  //проверяем, а есть ли окно для этого потока?                               //
  //Допустим, такого окна нет, это значит, что поток впервые будет что-то     //
  //писать.                                                                   //
  //тогда надо такое окно создать                                             //
  //pthread_mutex_lock (&mutex);                                              //
  if (TIDi_i_okna.find(TID_etogo_potoka)== TIDi_i_okna.end()) {               //
                                                                              //
   //Окно должно создастья в другом потоке                                    //
   //Дело в том, что в один поток не может одновременно создавать окно и      //
   //что-то туда                                                              //
   //писать. Этот поток пишет в окно. Значит, создавать окно должен           //
   //ДРУГОЙ ПОТОК                                                             //
   //И нам понадобится HWND этого окна                                        //
   HWND* pHWND= new HWND;                                                     //
   *pHWND= 0;                                                                 //
   pthread_t thread_t_okna;                                                   //
   pthread_create(&thread_t_okna, NULL, f_potoka_sozd_okna, pHWND);           //
   //Всё, есть новый поток и окно для него.                                   //
   //Теперь надо всё это занести в TIDi_i_TIDi                                //
                                                                              //
   //Это важно, ибо дальнейшая что-то должна происходит тогда, когда окно уже   //
   //создано, то есть pHWND должно стать коррекнтым более или менее, хе-хе    //
   while (!(*pHWND));                                                         //
    TIDi_i_okna [TID_etogo_potoka]= *pHWND;                                   //
  }                                                                           //
                                                                              //
                    //ну вё, тут собсно записывание                           //
  char* temp= new char [stroka.size()+ 1];                                    //
  strcpy (temp, stroka.c_str());                                              //
  temp [stroka.size()]= 0;                                                   //
  for (int j= 0; j< (int)strlen (temp); j++) {                                     //
   //Обязательно писать (unsigned char), благодаря этому в окне корректно обображается русский язык
   SendMessage ((HWND)TIDi_i_okna [TID_etogo_potoka], WM_CHAR, (unsigned char)temp [j], 1);  //
  }                                                                           //
  delete temp;                                                                              //
  return *this;
}                                                                             //
 
//++++++++++//++++++++++//++++++++++//++++++++++//++++++++++//++++++++++//
 
cout_ cout_::operator<< (int chislo) {
 char temp [256];
 itoa (chislo, temp, 10);
 string temp_ (temp);
 return (*this<< temp_);
}
 
 
 
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
              //реализацияреализацияреализацияреализация
                             //реализация
           
 
 
                          //Создание объекта
                              cout_ cout__;
                          //Создание объекта
 
 
//создаём окно создаём окно создаём окно создаём окно создаём окно создаём окно 
void* f_potoka_sozd_okna (void* pHWND) {                                           
             
           //Для начала определим координаты окна и его размеры
           //ЭТО x и y -координата верехнего левого угла окна  
           int x, y;
           
           pthread_mutex_lock (&_m__utex_); 
           if (f_chotchik_okon (cout__)< skolko_v_rad) {
            y= y_levii_verhni_ugol;  
            x= x_levii_verhni_ugol+  (shirina_okna+ \
               rasstoinie_mezhdu_oknami_po_gor)* \
               f_chotchik_okon (cout__);
            in_chotchik_okon (cout__);
           }   
           else if (f_chotchik_okon (cout__)< skolko_v_rad* 2) {
            y= y_levii_verhni_ugol+ visota__okna+ \
             rasstoinie_mezhdu_oknami_po_ver* (2- 1);
            x= x_levii_verhni_ugol;
            x= x_levii_verhni_ugol+  (shirina_okna+ \
               rasstoinie_mezhdu_oknami_po_gor)* \
               (f_chotchik_okon (cout__)- skolko_v_rad* (2- 1));
            in_chotchik_okon (cout__);
           }
           else if (f_chotchik_okon (cout__)< skolko_v_rad* 3) {
            y= y_levii_verhni_ugol+ (visota__okna+ \
               rasstoinie_mezhdu_oknami_po_ver)* (3- 1);
            x= x_levii_verhni_ugol;
            x= x_levii_verhni_ugol+  (shirina_okna+ \
               rasstoinie_mezhdu_oknami_po_gor)* \
               (f_chotchik_okon (cout__)- skolko_v_rad* (3- 1));
            in_chotchik_okon (cout__);
           }
 
           pthread_mutex_unlock (&_m__utex_);
           //с координтами разобрались                                        //
                                                                              //
           MSG messages;                                                      //
           *(HWND*)pHWND  = CreateWindowEx (                                  //
           0,                                                                 //
           "Edit",                                                            //
           NULL,                                                              //
           WS_OVERLAPPEDWINDOW|ES_MULTILINE|WS_VSCROLL|ES_AUTOVSCROLL,        //
           //CW_USEDEFAULT,                                                   //
           x, y, shirina_okna, visota__okna,                                  //
           NULL,                                                              //
           NULL,                                                              //
           0,                                                                 //
           NULL                                                               //
           );                                                                 //
           ShowWindow (*(HWND*)pHWND, SW_SHOWDEFAULT);                        //
           UpdateWindow (*(HWND*)pHWND);                                      //
           //= hwnd;                                                          //
                                                                              //
           while (GetMessage (&messages, NULL, 0, 0))    {                    //
            TranslateMessage(&messages);                                      //
            DispatchMessage(&messages);                                       //
           }                                                                  //
           return NULL;
}                                                                             //
//создаём окно создаём окно создаём окно создаём окно создаём окно создаём окно 
//недостаток: при закрытии какого-нибудь окна поток, пишущий в это окно, не   //
//закрывается и он продолжает писать, но в никуда. Чтобы его закрыть по       //
//закрытию окна, пишите свои оконные функции                                  //
#endif
kravam
быдлокодер
 Аватар для kravam
1513 / 873 / 44
Регистрация: 04.06.2008
Сообщений: 5,302
12.02.2012, 23:32  [ТС]     предлагаю людям класс "каждому потоку- своё окно" для тестирования многопоточных приложений. #3
Очередное улучшение: теперь можно сделать так, что при убивании (или как вариант самоубивании) потока убьётся и окошко, куда он выводит печать. (Добавлен то есть метод cout__.close() Это делается НЕ АВТОМАТИЧЕСКИ. необходимо позаботиться о том, чтобы при убивании потока был вызван этото метод. Можно также и при работе потока убить окно.

выкладываю код класса и демонстрационый пример:

НАпоминаю, что максимальное количество потоков 12 штук- больше нет смысла делать, все окошки не влезут в экран!
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
#ifndef MYCOUT___H
#define MYCOUT___H
 
 
#include <iostream> 
#include <pthread.h> 
#include <windows.h>
#include <stdio.h>
#include <sstream>
#include <map>
using namespace std;
                      /////////////////////////////////////
                      //это вот определяет координаты окон
                      /////////////////////////////////////
                      //////////и их количество////////////
 
#define skolko_v_rad 4
#define x_levii_verhni_ugol 100
#define y_levii_verhni_ugol 100
#define shirina_okna 250
#define visota__okna 200
#define rasstoinie_mezhdu_oknami_po_gor 20
#define rasstoinie_mezhdu_oknami_po_ver 20
                           //количество потоков-окон
#define kol_vo_potokov___ 12
                      /////////////////////////////////////
                      //это вот определяет координаты окон
                      /////////////////////////////////////
 
 
 
 
 
//А это мьютекс для того, чтобы корректно заносить в словарь
pthread_mutex_t _m__utex__= PTHREAD_MUTEX_INITIALIZER;
 
//Это чтобы ни с чем не спутать было
pthread_mutex_t _m__utex_= PTHREAD_MUTEX_INITIALIZER;
HWND hwnd [kol_vo_potokov___];
//класс класс класс класс класс класс класс класс класс класс класс класс 
//класс класс класс класс класс класс класс класс класс класс класс класс 
//класс класс класс класс класс класс класс класс класс класс класс класс 
//класс класс класс класс класс класс класс класс класс класс класс класс 
class cout_ {
 public:
  cout_ () {chotchik_okon= 0;}
 ~cout_ () {}
 
  //главная функция, из-за которой вся эта бодяга затеяна
  cout_ operator<< (string);
 
  //Будем работать также и с int!
  cout_ operator<< (int);
 
  //А эта функция служит для закрывания окна
  void close();
    
 
 private:
 
  //Эта вот есть словарь, ключи- TIDi потоков-писаталей
  //значения- HWND окон                                     
  map <HANDLE, HWND> TIDi_i_okna;
 
  
  //Счётчик окон и функции, которые его инкременируют и возвращают,
  //зачем-то я их сделал дружественными                            
  int chotchik_okon;   
  friend int f_chotchik_okon (cout_& cout__){return cout__.chotchik_okon;}
  friend void in_chotchik_okon (cout_& cout__){++cout__.chotchik_okon;}
 
};
//класс класс класс класс класс класс класс класс класс класс класс класс 
//класс класс класс класс класс класс класс класс класс класс класс класс 
//класс класс класс класс класс класс класс класс класс класс класс класс 
//класс класс класс класс класс класс класс класс класс класс класс класс 
 
 
 
//Это будет функция потока, который создаёт окна.                             
//если выяснитс, что поток, которым мы собираемся чё-то писать, вообще впервые
//включился в эту бодягу, то необходимо создать для него окно.                
//за создание окна отвечает, опять, же- другой поток. НАзовём его X           
//причём, что интересно- этот X может создавать только одно окно              
//поскольку это необходимо делать в разные моменты времени, по мере надобости 
//ВЫвод: таких иксов может и должно быть много                                
//тупо: на каждый пишущий поток своё окно и свой поток, который это окно      
//создаст.                                                                    
//А вот его функция, она ничё не может возвернуть, поскольку кропает цикл     
//приёмки сообщений для окна                                                  
void* f_potoka_sozd_okna (void*);
                                    //
                                    //
                                    //
                                    //
 
                               //реализация
              //реализацияреализацияреализацияреализация
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
cout_ cout_::operator<< (string stroka) {                                  //
                                                                              //
  HANDLE TID_etogo_potoka= *(HANDLE*)(pthread_self().p);                      //
                                                                              //
                                                                              //
  //проверяем, а есть ли окно для этого потока?                               //
  //Допустим, такого окна нет, это значит, что поток впервые будет что-то     //
  //писать.                                                                   //
  //тогда надо такое окно создать                                             //
  pthread_mutex_lock (&_m__utex__);                                              //
  if (TIDi_i_okna.find(TID_etogo_potoka)== TIDi_i_okna.end()) {               //
   //pthread_mutex_unlock (&_m__utex__);                                              //
                                                                              //
   //Окно должно создастья в другом потоке                                    //
   //Дело в том, что в один поток не может одновременно создавать окно и      //
   //что-то туда                                                              //
   //писать. Этот поток пишет в окно. Значит, создавать окно должен           //
   //ДРУГОЙ ПОТОК                                                             //
   //И нам понадобится HWND этого окна                                        //
   HWND* pHWND= new HWND;                                                     //
   *pHWND= 0;                                                                 //
   pthread_t thread_t_okna;                                                   //
   pthread_create(&thread_t_okna, NULL, f_potoka_sozd_okna, pHWND);           //
   //Всё, есть новый поток и окно для него.                                   //
   //Теперь надо всё это занести в TIDi_i_TIDi                                //
                                                                              //
   //Это важно, ибо дальнейшая херь должна происходит тогда, когда окно уже   //
   //создано, то есть pHWND должно стать коррекнтым более или менее, хе-хе    //
   while (!(*pHWND)) {                                                        //
    Sleep (10);                                                               //              
   };                                                                         //
   TIDi_i_okna [TID_etogo_potoka]= *pHWND;                                    //
  }                                                                           //
  pthread_mutex_unlock (&_m__utex__);                                         //
                                                                              //
                    //ну вё, тут собсно записывание                           //
  char* temp= new char [stroka.size()+ 1];                                    //
  strcpy (temp, stroka.c_str());                                              //
  temp [stroka.size()]= 0;                                                    //
  for (int j= 0; j< (int)strlen (temp); j++) {                                //
   //Обязательно писать (unsigned char), благодаря этому в окне корректно обображается русский язык
   SendMessage ((HWND)TIDi_i_okna [TID_etogo_potoka], WM_CHAR, (unsigned char)temp [j], 1);  //
  }                                                                           //
  delete temp;                                                                //
  return *this;                                                               //
}                                                                             //
 
//++++++++++//++++++++++//++++++++++//++++++++++//++++++++++//++++++++++//
 
cout_ cout_::operator<< (int chislo) {
 char temp [256];
 itoa (chislo, temp, 10);
 string temp_ (temp);
 return (*this<< temp_);
}
 
//++++++++++//++++++++++//++++++++++//++++++++++//++++++++++//++++++++++//
 
                          //    закрывание окна 
                 //    закрывание окна закрывание окна     
//    закрывание окна закрывание окна закрывание окна закрывание окна     
void cout_::close () {
 HANDLE TID_etogo_potoka= *(HANDLE*)(pthread_self().p); 
 SendMessage ((HWND)TIDi_i_okna [TID_etogo_potoka], WM_CLOSE, 0, 0);
 
 //Удаляем все упоминания о потоке из списка-словаря                      
 if (!(TIDi_i_okna.erase(TID_etogo_potoka))) 
  printf ("Всё плохо, поток с TIDом %x не удалился\n", TID_etogo_potoka);
}
//    закрывание окна закрывание окна закрывание окна закрывание окна     
                 //    закрывание окна закрывание окна     
                          //    закрывание окна 
 
 
 
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
              //реализацияреализацияреализацияреализация
                             //реализация
           
 
 
                          //Создание объекта
                              cout_ cout__;
                          //Создание объекта
 
 
//создаём окно создаём окно создаём окно создаём окно создаём окно создаём окно 
void* f_potoka_sozd_okna (void* pHWND) {                                           
             
           //Для начала определим координаты окна и его размеры
           //ЭТО x и y -координата верехнего левого угла окна  
           int x, y;
           
           pthread_mutex_lock (&_m__utex_); 
           if (f_chotchik_okon (cout__)< skolko_v_rad) {
            y= y_levii_verhni_ugol;  
            x= x_levii_verhni_ugol+  (shirina_okna+ \
               rasstoinie_mezhdu_oknami_po_gor)* \
               f_chotchik_okon (cout__);
            in_chotchik_okon (cout__);
           }   
           else if (f_chotchik_okon (cout__)< skolko_v_rad* 2) {
            y= y_levii_verhni_ugol+ visota__okna+ \
             rasstoinie_mezhdu_oknami_po_ver* (2- 1);
            x= x_levii_verhni_ugol;
            x= x_levii_verhni_ugol+  (shirina_okna+ \
               rasstoinie_mezhdu_oknami_po_gor)* \
               (f_chotchik_okon (cout__)- skolko_v_rad* (2- 1));
            in_chotchik_okon (cout__);
           }
           else if (f_chotchik_okon (cout__)< skolko_v_rad* 3) {
            y= y_levii_verhni_ugol+ (visota__okna+ \
               rasstoinie_mezhdu_oknami_po_ver)* (3- 1);
            x= x_levii_verhni_ugol;
            x= x_levii_verhni_ugol+  (shirina_okna+ \
               rasstoinie_mezhdu_oknami_po_gor)* \
               (f_chotchik_okon (cout__)- skolko_v_rad* (3- 1));
            in_chotchik_okon (cout__);
           }
 
           pthread_mutex_unlock (&_m__utex_);
           //с координтами разобрались                                        //
                                                                              //
           MSG messages;                                                      //
           *(HWND*)pHWND  = CreateWindowEx (                                  //
           0,                                                                 //
           "Edit",                                                            //
           NULL,                                                              //
           WS_OVERLAPPEDWINDOW|ES_MULTILINE|WS_VSCROLL|ES_AUTOVSCROLL,        //
           //CW_USEDEFAULT,                                                   //
           x, y, shirina_okna, visota__okna,                                  //
           NULL,                                                              //
           NULL,                                                              //
           0,                                                                 //
           NULL                                                               //
           );                                                                 //
           ShowWindow (*(HWND*)pHWND, SW_SHOWDEFAULT);                        //
           UpdateWindow (*(HWND*)pHWND);                                      //
           //= hwnd;                                                          //
                                                                              //
           while (GetMessage (&messages, NULL, 0, 0))    {                    //
            TranslateMessage(&messages);                                      //
            DispatchMessage(&messages);                                       //
           }                                                                  //
           return NULL;
}                                                                             //
//создаём окно создаём окно создаём окно создаём окно создаём окно создаём окно 
//недостаток: при закрытии какого-нибудь окна поток, пишущий в это окно, не   //
//закрывается и он продолжает писать, но в никуда. Чтобы его закрыть по       //
//закрытию окна, пишите свои оконные функции                                  //
#endif


Ну и как использовать:
Создаются потоки, выводящие свои TIDы в бесконечном цикле, как только они по 5 раз тиды выведут, некоторые самоубьются, какие- решит жребий. ПРи самоубивании исчезнут и их окна.
После чего можно какой-нибудь поток убить вручную и увидеть, как его окно тоже убьётся.


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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <mycout__.h>
#define kol_vo_potokov 12
 
/////////////////////////////////////////////////////////////////////////////
//А это вот типа деструктора потока. в данный момент я возлагаюна него
//одну задачу- убить окно!
void routine  (void* x) {
 cout__ <<string("видать, пришла пора самоубиться\n");
 Sleep (5000);
 cout__.close();
}
 
 
 
//Это функция потока-писателя
void *task1 (void* po) { 
 
   //Тут мы типа объявили деструктор потока
   pthread_cleanup_push (&routine, 0); 
 
 
   int i= 0;
 
   //РАзберёмся с TIDами
   char buffer [256];
   pthread_t pthread_t_ = pthread_self();
   int TID= *(int*)(pthread_t_.p);
   itoa (TID, buffer, 16);
   int temp= strlen (buffer);
   buffer [temp]= 0;
 
 
   time_t lt;
   
   while (true) { 
    srand(lt = time(NULL));
    
    //Любым способом можно выводить чё надо
    //cout__<< string(strcat(strcat (buffer, "__"), ctime(&lt))) ;
    //cout__<< string(buffer)<<string(" ")<< string(ctime(&lt));
    cout__<< string("мой TID и время соответственно ")<< TID <<string(" ")<< string(ctime(&lt));
    i++;
    
    cout__<< i<< string(" \n");;
    if (i== 5) {
     int temp= rand();
     if (temp%2) {
      cout__<< string ("пршло 5 итераций цикла, мой temp%2 ")<<temp%2<< string (" и я щас самоубьюсь\n");
      Sleep (5000);
      pthread_exit(0);   
     }
    } 
    if (i> 5){
      cout__<< string ("\nА я не собираюсь самоубиваться!\n");
    }
    Sleep (1000+ TID%1000);
    
    //Контрольная точка
    pthread_testcancel(); 
    
    
  
   }
 
   //Тут вот активируем деструктор потока 
   pthread_cleanup_pop (false); 
 
 return NULL;
} 
/////////////////////////////////////////////////////////////////////////////
 
 
int main(int argc, char *argv[]) { 
 SetConsoleCP (1251);
 SetConsoleOutputCP (1251);
 //srand (time(0));
 
 //TID убивающегося потока
 int TID;
 
 
 //Объявляем потоки
 pthread_t array_p [kol_vo_potokov];
 //создаём
 for (int i= 0; i< kol_vo_potokov; i++) {
  Sleep (1000);
  pthread_create(&array_p[i],NULL,task1, NULL); // Создаем  потоки. 
 }
 
 cout<< "ПО окончании самоубиения потоков введи TID того, который ты хочешь убить вручную"<< endl;
 cin>> TID;
 int i;
 for (i= 0; i< kol_vo_potokov; i++) {
  if (TID== *(int*)array_p[i].p) {
   pthread_cancel(array_p[i]); 
   break;
  }
 }
 
 if (i== kol_vo_potokov)
  cout<< "ПОтока с таким TIDом нет"<< endl;
  
 // Дополнительная обработка. 
 for (int i= 0; i< kol_vo_potokov; i++) {
  pthread_join(array_p[i],NULL); // Ожидание завершения 
 }
 
 getchar ();
 return (0) ; 
}
kravam
быдлокодер
 Аватар для kravam
1513 / 873 / 44
Регистрация: 04.06.2008
Сообщений: 5,302
13.02.2012, 00:39  [ТС]     предлагаю людям класс "каждому потоку- своё окно" для тестирования многопоточных приложений. #4
Чтобы было понятнее о чём речь: вот такие у вас аккуратные окошки будут:
Миниатюры
предлагаю людям класс "каждому потоку- своё окно" для тестирования многопоточных приложений.  
Yandex
Объявления
13.02.2012, 00:39     предлагаю людям класс "каждому потоку- своё окно" для тестирования многопоточных приложений.
Ответ Создать тему
Опции темы

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