Jak przenieść własność wątku do klasy?

0

Od razu mówie że dopiero zaczynam z wątkami.
i tak che sobie zrobić taką klase które wykona metode join jeśli funkcje tworząca obiekt się skończy a wątek jeszcze nie.
i tak problem jest taki że to nie działa. Kiedy próbuje przekazać wątek do klasy, tak żeby zmienna w tej klasie była jedynym posiadaczem własności
to potem wszędzie mam podkreślone t1, jak prubuje wywołać jakąś metodę w tym wypadku a, tak jak by to niebyła obiekt klasy.
a przydały by się metody które zwrucą np ID wątku. ca ja tu robie źle ??

#ifndef __header_h
#define __header_h

#include <iostream>
#include <string>
#include <thread>

class test
{
	private:
		int& m_i;
	public:
		test(int& i) : m_i(i) {}
		void operator()();
};

class test2
{
public:
	void operator()();
};

class thread_guard
{
	private:
		std::thread m_t;
	public:
		thread_guard(){};
		thread_guard(std::thread t) : m_t(std::move(t)) {}
		~thread_guard() { m_t.join(); }

		void a(void) { std::cout << "aaaaaa" << std::endl; }
};

#endif
#include <iostream>
#include <algorithm>
#include <memory>
#include <thread>
#include "Header.h"

void fun1(int & x)
{
	std::cout << "Zmienna x ktora jest referencja do i: " << x << std::endl;
	while (x < 100)
		x++;

	std::cout << "Zmienna x ktora jest referencja do i: " << x << std::endl;
}

int main(void)
{
	int i = 0;
	int j = 0;

	std::unique_ptr<test2> u_ptr(new test2);

	//test  ob1(j);
	test2 ob2;

	thread_guard t1(std::thread(test(j)));
	std::thread t2(fun1, std::ref(i));
	//std::thread t3(u_ptr);	
	//t1.a();

	std::cout << "Zmienna i: " << i << std::endl;
	std::cout << "Zmianna j: " << j << std::endl;
	//std::cout << "ID watku t1: " << t1.get_thread() << std::endl;
	std::cout << "ID watku t2: " << t2.get_id() << std::endl;
	std::cout << "ID Obecnego watku: " << std::this_thread::get_id() << std::endl;
	std::thread t3 = std::move(t2);
	//std::cout << "ID watku t1: " << t1.get_thread().get_id() << std::endl;
	std::cout << "ID watku t2: " << t2.get_id() << std::endl;

	t2.join();
}
1

Zbyt wiele z tego nie zrozumiałem. Jakbyś mógł, opisz swój problem w lepszy sposób.

Ale...

Kosimazaki123 napisał(a):
...
	std::thread t3 = std::move(t2);
...
	t2.join();
}

Wiesz, że jeżeli na obiekcie zostało użyte std::move, to już dalej nie można z niego korzystać?

0

hmm.
Chodzi mi o to żebym nie musiał dbać o wywołanie metody join przed końcem funkcji która ten wątek stworzyła.
wraz z końcem funkcji wszystkie zmienne oraz obiekty są usuwane. Kiedy to usuwamy obiekt wywoła si destruktor.
A w destruktorze będzie join.
I jak widać w moim kodzie na konstruktorze thread_guard tworze od razu wątek i używam std::move żeby z obiektu tymczasowego przenieść na zmienną prywatną klasy.

obiekt się niby tworzy. ale próba wywołania metody

t1.a();

wywołuje błąd

error C2228: left of '.a' must have class/struct/union
kiedy użyje konstruktora domyślnego który nic nie robi metode moge użyć.
a kompilacja bez tego fragmentu, jak widać jest zakomentowany

program się uruhamia i leci takie coś

Unhandled exception at 0x000007FEFC5C940D in Project8.exe: Microsoft C++ exception: std::system_error at memory location 0x00000000001EF6D0.

dodanie znaczników <code> i `` - furious programming

1

W takim razie przyjmuj referencję do wątku, a nie wątek przez kopię. Poza tym, zamiast wymyślać koło na nowo możesz użyć jakiegoś scope guarda, np. Boost.ScopeExit ( http://www.boost.org/doc/libs/1_56_0/libs/scope_exit/doc/html/index.html ) lub nawet std::unique_ptr: http://melpon.org/wandbox/permlink/tvewIblWdZ9Qzytl http://melpon.org/wandbox/permlink/jLeCbYqOH2vrqEIW

0

ale jak się uczę to można takie rzeczy pisać, żeby to zajarzyć.
I jak używam move to własność się powinna przenieść
ale coś nie działa

0

Move to jest koncept, tak naprawdę to jest nic innego jak rvalue_cast<>

A co do Twojego problemu, najwyraźniej dałeś się złapać w most vexing parse: http://en.wikipedia.org/wiki/Most_vexing_parse

thread_guard t1{std::thread(test(j))};

lub

thread_guard t1((std::thread(test(j))));

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