Wątek w klasie

0

Chciałbym mieć taką klasę:

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?
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:

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

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

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

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

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.

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.

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

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.

1 użytkowników online, w tym zalogowanych: 0, gości: 1