powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Linux: C++, GUI, thread
10 сообщений из 35, страница 2 из 2
Linux: C++, GUI, thread
    #39138769
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex_KaПросто с потоками разобрался кажется. Теперь задача посложнее будет.
Надо сделать потоки-классы(как в java) на c++ под линукс.

Итак, надо чтобы в основном потоке были 2-е функции которые позволяют основному и рабочим потокам изменять и читать состояние некого объекта(obj) - для этого надо сделать эти функции(или часть кода в них) потокобезопасными, возникают 2 вопроса:
1. как пользоваться мутексами для этого? (или нужно что-то другое?)
2. как написать класс поток? (если это возможно?) //желательно чтобы рабочие потоки ничего не делали пока ожидают смены состояния объекта obj и чтобы основной поток мог уведомить рабочие потоки при смене статуса объекта obj.

и еще вопрос, можно-ли в потоке-классе написать функцию которая будет callback если да то как например при наличии 1000 объектов-потоков будет вызываться нужная функция сторонним приложением?

вообще-то в с++ все классы для этого уже есть.
ссылку тебе уже дали.
...
Рейтинг: 0 / 0
Linux: C++, GUI, thread
    #39138903
Alex_Ka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
За ссылку спасибо.
как "выполнить функцию" в потоке понятно, а вот как свой класс-поток создать еще нет, так что пока разбираюсь если кто поделился бы примером то было бы очень кстати.

И вопрос про callback функции остается, можно-ли сделать так чтобы стороннее приложение вызывало функцию объекта? (не просто функцию и не статическую функцию)
...
Рейтинг: 0 / 0
Linux: C++, GUI, thread
    #39138904
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex_Kaкак свой класс-поток создать еще нет
И не будет. Потому что не бывает в природе "класс-потоков".
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Linux: C++, GUI, thread
    #39138907
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex_KaЗа ссылку спасибо.
как "выполнить функцию" в потоке понятно, а вот как свой класс-поток создать еще нет, так что пока разбираюсь если кто поделился бы примером то было бы очень кстати.
Что ты понимаешь под "класс-поток" ? Поток это функция, как завершилась - так завершился поток.

Если вопрос стоит как работать с объектом в отдельном потоке, то передаешь указатель на объект в параметрах.

Alex_KaИ вопрос про callback функции остается, можно-ли сделать так чтобы стороннее приложение вызывало функцию объекта? (не просто функцию и не статическую функцию)
Что значит "стороннее приложение" ? Поконкретнее распиши что там у тебя происходит.
...
Рейтинг: 0 / 0
Linux: C++, GUI, thread
    #39138963
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex_KaИ вопрос про callback функции остается, можно-ли сделать так чтобы стороннее приложение вызывало функцию объекта? (не просто функцию и не статическую функцию)

Что такое стороннее приложение не знаю, но колбэк из объектной функции создается и вызывается так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
class A {
  public:
  void callback(int arg);
};
A a;

auto fn = std::bind(&A::callback, &a, 123);
fn();



И естественно, если вы передаете колбэк в поток, то вы должны гарантировать что объект для которого он вызывается будет существовать в момент вызова из потока.
...
Рейтинг: 0 / 0
Linux: C++, GUI, thread
    #39142057
Alex_Ka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
спасибо за ответы.
вот еще вопросы возникли, создаю я класс(примерно такой):
Код: plaintext
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.
//userdataworker.h
#ifndef USERDATAWORKER_H_
#define USERDATAWORKER_H_

#pragma once /* Защита от двойного подключения заголовочного файла */
#include <string>

class UserDataWorker{

  private:
    char* ClientCode;
    int Port;
    int Num;
    double LLevel;

  public:
    UserDataWorker(/*char*/const char* ClientCode, int Port, int Num, double LLevel);
    ~UserDataWorker();

    void getStateUserData(char* _ClientCode, int* _Port, int* _Num, double* _LLevel);
    void printStateUserData();
    int runner();
    int serviceCallback();
};
#endif /* USERDATAWORKER_H_ */



Код: plaintext
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.
// userdataworker.cpp
#include "userdataworker.h"
#include <string>
#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;

UserDataWorker::UserDataWorker(/*char*/const char* _ClientCode, int _Port, int _Num, double _LLevel)
{
  //cout << "UserData_CONSTRUCTOR in param _ClientCode:" << _ClientCode << " port: " << _Port << " num: " << _Num << " l: " << _LLevel << endl;

  ClientCode = new char[sizeof(_ClientCode)];
  strcpy(ClientCode, _ClientCode);
  Port = _Port;
  Num = _Num;
  LLevel = _LLevel;
  std::cout << "UserData_CONSTRUCTOR_ClientCode: " << ClientCode << " Port: "
         << Port << " Num: " << Num << " LLevel: " << LLevel << std::endl;
}

UserDataWorker::~UserDataWorker()
{
    cout << "UserData_destructor. ClientCode:" << ClientCode << endl;
    //delete []ClientCode; //надо освобождать память?
}

void UserDataWorker::getStateUserData(char* _ClientCode, int* _Port, int* _Num, double* _LLevel)
{
  strcpy(_ClientCode, ClientCode);
  _Port = &Port;
  _Num = &Num;
  _LLevel = &LLevel;
}

void UserDataWorker::printStateUserData()
{
  std::cout << "printStateUserData ClientCode: " << ClientCode << " Port: "
         << Port << " Num: " << Num << " LLevel: "
         << LLevel << std::endl;
}

int UserDataWorker::runner()
{
  //что-то делаем в потоке.
  return 0;
}

int UserDataWorker::serviceCallback()
{
    //вызов из вне
}



как мне сделать стобы функция runner() вызывалась в потоке?
пытаюсь так, но не получается(ошибка: нет подходящей функции для вызова...)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
int main(int argc, char* argv[])
{
	for ( int idx = 0; idx < 10; ++idx )
	{
		std::stringstream ss;
		ss << "thread_" << idx;

		UserDataWorker userDataWorker(ss.str().c_str(), 3000 + idx, 10 * idx, 0.5 + idx);

		std::thread myThread(userDataWorker.runner );
		myThread.detach();
		//std::thread(userDataWorker.runner ).detach();
	} 
  return 0;
}



надо ли мне в деструкторе освобождать память?
...
Рейтинг: 0 / 0
Linux: C++, GUI, thread
    #39142064
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex_Kaнадо ли мне в деструкторе освобождать память?Восходит ли солнце на востоке?
...
Рейтинг: 0 / 0
Linux: C++, GUI, thread
    #39142069
Alex_Ka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
:)

а как мне тут:
std::thread myThread(userDataWorker.runner );
правильно вызвать мою функцию в потоке?
...
Рейтинг: 0 / 0
Linux: C++, GUI, thread
    #39142072
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex_Ka:)

а как мне тут:
std::thread myThread(userDataWorker.runner );
правильно вызвать мою функцию в потоке? http://en.cppreference.com/w/cpp/thread/thread/thread
...
Рейтинг: 0 / 0
Linux: C++, GUI, thread
    #39146718
Alex_Ka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
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.
#include <thread>
#include <string>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <ctime>
#include <chrono>
#include <sstream>

long any_var = 1234;
double any_ln = 1001.01010111;

class MyThread{ 
private:
  char* ClientCode;
  int id;
  long userID;
  volatile bool stopThread;
  double *LnValue;
  long *var;
  long counter;
  volatile long c2;
  //static long s = 0;
  
public:
  MyThread(const char* _ClientCode, int param_id, long param_userID, double *_LnValue, long *_var) 
  : id(param_id)
  , userID(param_userID)
  , LnValue(_LnValue)
  , var(_var)
  , counter(0)
  , c2(0)
  , stopThread(false)
  {
    ClientCode = new char[sizeof(_ClientCode) + 1];
    strcpy(ClientCode, _ClientCode); 
  }

  ~MyThread()
  {
    //delete []ClientCode;
    //delete ClientCode;
    //delete &ClientCode;
    //delete *ClientCode;
  } 
  
  void run_thread() //volatile
  {
    counter = (id+1) * 1000000000;
  	while(!stopThread && *var != -1)
  	{
	  counter++;
  	std::cout << "THREAD : " << id << " userID: " << userID << " T_ID: " << std::this_thread::get_id() << " ClientCode: " << ClientCode << " stopThread: " << stopThread << " var: " << *var << " LnValue: " << *LnValue << " c= " << counter << " c2= " << c2  << std::endl;
		//DO ANY LOGIC IN THREAD
  		std::this_thread::yield();
		std::this_thread::sleep_for(std::chrono::microseconds(700));
		c2++;
  	}
  }
  
  void stop_thread()
  {
  	stopThread = true;
	std::cout << "stop_thread_THREAD : " << id << " userID: " << userID << " T_ID: " << std::this_thread::get_id() << " ClientCode: " << ClientCode << " stopThread: " << stopThread << " c2= " << c2 << std::endl;
  } 
    
};
 
int main(int argc, char* argv[]){
 
std::vector<MyThread> threads;
int treads_num = 5;

for ( int num = 0; num < treads_num; num++ )
{
	std::stringstream ss;
	ss << "thread_" << num;
		
	MyThread t(ss.str().c_str(), num, num * 1000, &any_ln, &any_var);

	std::thread my_thread(&MyThread::run_thread, t);
		
	my_thread.detach();
		
	threads.push_back( t );
}

    std::this_thread::sleep_for(std::chrono::milliseconds(50));

for (int m=0; m<threads.size(); m++)
{
  threads.at(m).stop_thread();
}  
 
any_var = -1; 
 
std::this_thread::sleep_for(std::chrono::milliseconds(50));
std::cout << "MAIN_THREAD FINISH" << std::endl;

return 0;
}


Вот мой тестовый код, он рабочий, но по нему есть вопросы, ответьте кто знает плс. :
1. при вызове stop_thread из основного потока переменная stopThread не изменяется, хотя объявлена volatile почему?
как сделать чтобы она изменялать? только через указатели?
2. как мне правильно освобождать память в деструкторе?
3. как мне использовать статическую переменную для подсчета созданных объектов? и вобще статические переменные как им задавать значения кроме конструктора?
...
Рейтинг: 0 / 0
10 сообщений из 35, страница 2 из 2
Форумы / C++ [игнор отключен] [закрыт для гостей] / Linux: C++, GUI, thread
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]