Wątek w klasie

LE
  • Rejestracja:prawie 6 lat
  • Ostatnio:około 4 lata
  • Postów:41
0

Chciałbym mieć taką klasę:

Kopiuj
class Example
{
private:
	std::thread th;
	void foo()
	{
		int x = 0;
		while (true)
			std::cout << ++x << std::endl;
	}
public:
	Example(int x)
	{
		th = std::thread(foo); // Błąd
		th.detach();
	}
	~Example()
	{
		// zatrzymanie watka
	}
};

  1. Jak zainicjować ten wątek?
  2. Chciałbym, żeby wątek działał tak długo jak obiekt tej klasy jest na stosie/stercie.
  • Zatrzyma się sam na przykład po "delete example"?
  • Powinienem zastosować RAII(jak wyłączyć wątek?)?
  • Istnieje jakiś mechanizm oparty na RAII, coś w stylu "thread_guard"?
  1. Jeśli włączę kilka wątków, które korzystają z std::cout / std::endl to często napisy pojawiają się w jednej linii, czy to wynika z jednego bufora? Jak tego uniknąć?
  2. Zawsze widzę, że destruktory klas są publiczne, ale właściwie dlaczego, czy to dobra praktyka?
MarekR22
Moderator C/C++
  • Rejestracja:ponad 17 lat
  • Ostatnio:2 minuty
5

Offtopic:
Takie użycie wątku, to błąd architektoniczny. Lepiej osobno mieć logikę obliczeń, a osobno logikę, która wkłada to do wątku.

Ontopic:

Kopiuj
th = std::thread(&Example::foo, this);

Jako, że foo jest metodą, to ma cichy argument this, który trzeba przekazać do std::thread.

Funkcje dla std::cin i std::cout są atomowe, ale nie wcale nie znaczy, to, że zapis linii jest atomowy.
Np to wywołane na wielu wątkach

Kopiuj
std::cout << "jakies cudo" << std::endl;

może spowodować, łączenie linii, bo to jest wywołanie dwóch funkcji


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 4x, ostatnio: MarekR22
MarekR22
Moderator C/C++
  • Rejestracja:ponad 17 lat
  • Ostatnio:2 minuty
4

Jako, że podejrzewam, że jesteś początkujący, gorąco cię ZNIECHĘCAM do używania wątków.
Wątki mają dużo wad:

  • wydają się łatwe (przez co jest masę tutoriali pisanych, przez ludzi nie mających o nich pojęcia)
  • jest na nie niezdrowa moda (wiele rzeczy, które można zrobić prościej inaczej, dostaje wątki)
  • błędy wielowątkowości, są bardzo niedeterministyczne, ich analiza i naprawianie jest bardzo trudne
  • używając ich trzeba zachować ścisłą dyscyplinę
  • bez ogarnięcia podstaw można mieć wrażenie, że coś się umie na ich temat, albo doprowadzić sie do takiej irytacji, że zakończysz zabawę z programowaniem.
  • z mojego doświadczenia, 80% "zawodowców" jest jedynie przekonana, że umie ich używać nawet w zakresie podstawowym.

Lepiej spożytkujesz czas skupiając się na czymś innym. Np na pisaniu testów używając gtest albo catch2


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 2x, ostatnio: MarekR22
Sunnydev
jak się w takim razie Ty nauczyłeś wielowątkowości? już w pracy czy samemu coś kombinowałeś?
MarekR22
a kto powiedział, że się nauczyłem? :) Wiem jak wiele nie wiem. Efekt Dunninga-Krugera
Sunnydev
a no dobra xD zawsze myślałem, że Ty w tym siedzisz po uszy :)
LE
  • Rejestracja:prawie 6 lat
  • Ostatnio:około 4 lata
  • Postów:41
0

@MarekR22:
Konstrukcja z this nie działa: error C3867: 'Example::foo': non-standard syntax; use '&' to create a pointer to member. Dla th = std::thread(&foo, this); też jest błąd, error C2276: '&': illegal operation on bound member function expression.
Co do wątków - jak dotąd nie używałem ich w ogóle, naukę zacząłem ze względu na tę "modę", wydaje mi się, że znalezienie pracy w C++ bez podstawowej znajomości wątków jest znacznie trudniejsze.
A co do przykładu z tytułowego posta, chciałbym zrobić symulator algorytmów i potrzebuję dodatkowego wątku do rysowania okna, wydaje się to rozsądne(?) zastosowanie wielowątkowości.

MarekR22
Moderator C/C++
  • Rejestracja:ponad 17 lat
  • Ostatnio:2 minuty
3

https://godbolt.org/z/eh6d31

Skoro masz problem z takim prostym błędem, to na wątki jest dla ciebie dużo za wcześnie.
Ale skoro chcesz zmarnować trochę czasu, to twoja sprawa.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
SL
  • Rejestracja:około 7 lat
  • Ostatnio:około 6 godzin
  • Postów:902
2
leto napisał(a):

A co do przykładu z tytułowego posta, chciałbym zrobić symulator algorytmów i potrzebuję dodatkowego wątku do rysowania okna, wydaje się to rozsądne(?) zastosowanie wielowątkowości.

Jeśli już to dodatkowy wątek do obliczeń, ale i tak wątpię, czy w tym przypadku jest to potrzebne. Generalnie programowanie okienek i wątki to coś, czego się nie łączy. W książce "Java Concurrency in Practice" jest fajny rozdział opisujący dlaczego nie powinno się używać wątków w programowaniu GUI. Najrozsądniejszym zachowaniem jest obsługa okien w głównym wątku i ewentualne delegowanie obliczeń do innych wątków np. za pomocą std::future

tajny_agent
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad rok
  • Postów:1340
1
leto napisał(a):
  1. Chciałbym, żeby wątek działał tak długo jak obiekt tej klasy jest na stosie/stercie.
  • Zatrzyma się sam na przykład po "delete example"?
  • Powinienem zastosować RAII(jak wyłączyć wątek?)?
  • Istnieje jakiś mechanizm oparty na RAII, coś w stylu "thread_guard"?

Świeżynka o std::thread i std::jthread

  1. Zawsze widzę, że destruktory klas są publiczne, ale właściwie dlaczego, czy to dobra praktyka?

Jest kilka przypadków gdy prywatny destruktor ma sens, ale to wyjątki.


"I love C++. It's the best language in the world right now for me to write the code that i need and want to write"
~ Herb Sutter

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.