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

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

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Центр графа http://www.cyberforum.ru/cpp-beginners/thread380460.html
Дана матрица смежности. Найти максимальное расстояние в графе. Пол дня уже мучаюсь, искал в гугле, сам пытался, но ничего не получается... просто тупик... Код вылаживать не буду, так как он не правильный. Просто расскажу, как я хочу сделать. Беру первую вершину, и делаю ее текущей. Если существует ребро между текущей и другой вершиной, делаю ее текущей и иду дальше. При этом считаю все...
C++ задача со строками пожалуйста, помогите. Нужно написать программу , которая определит длину введенной строки L, и, если L>10, то удаляются все цифры. я так понял, что в строке должны быть и цифры и буквы http://www.cyberforum.ru/cpp-beginners/thread380453.html
Перехват запросов C++
Здравствуйте Форумчане, у меня возникла проблема, я хочу сделать что-то вроде веб-логгера который будет перехватывать запросы и т.д. Не подскажите ли Вы мне как это можно реализовать. Заранее спасибо.
C++ Ввод из файла символьного массива
Как ввести вот такой символьный массив из файла ? 2X11 X121 12X1 1112 2222 XXX2 X21X 1X2X
C++ Поменять местами каждые соседние слова http://www.cyberforum.ru/cpp-beginners/thread380419.html
Написать программу, которая считывает текст с клавиатуры и выводит его на экран, меняет местами каждые соседние слова (Borland MS-DOS)
C++ цикл с параметром доно число N >0. найти значение выражения: 1,1 - 1,2 + 1,3 - ... (N слагаемых, знаки чередуются) include <iostream> using namespace std; int n,i; double summa,t; int main() { подробнее

Показать сообщение отдельно
kravam
быдлокодер
1694 / 881 / 44
Регистрация: 04.06.2008
Сообщений: 5,441
12.02.2012, 23:32  [ТС]
Очередное улучшение: теперь можно сделать так, что при убивании (или как вариант самоубивании) потока убьётся и окошко, куда он выводит печать. (Добавлен то есть метод 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) ; 
}
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru