[C++] Wywołania metody obiektu globalnego w wątkach

0

Próbuję napisać prosty wielowątkowy serwer, który będzie... coś tam, coś tam... nie ważne. Nadmienię, iż nie mam zbytniego doświadczenia z programowaniem wielowątkowym. I w pewnym punkcie tego programu wymyśliłem sobie coś na kształt:

class Command
{
	private:
		int m_iNumber;
		int m_iLevel;
		
		(...)	
		
		friend class CommandMap;
			
};

class CommandMap
{
	private:
		map<string, Command> m_commandMap;
		
		(...)
		
	public:
		int checkCommand(int iLevel, string sCmd);
		
		(...)
		
		friend class Command;
};

(...)

int CommandMap::checkCommand(int iLevel, string sCmd) //tutaj może referencje
{
	map<string, Command>::iterator it;
	
	it = this->m_commandMap.find(sCmd);
	
	if(it != map::end)
		if(it->second.m_iLevel == iLevel) 
			return it->second.iNumber;
		
	return -1;
}

(...)
CommandMap myProtocol;

(...)

	//gdzieś w funkcji wątku
	iCurrentNumber = myProtocol.checkCommand(iCurrentLevel, sCurrentCommand);

A więc istnieje globalny obiekt klasy CommandMap, który chciałbym, aby reprezentował możliwe do wykonania komendy na poszczególnych etapach połączenia. Teraz powiedzmy, że gdzieś w wątku będą się pojawiały wywołania funkcji tego obiektu, której zadaniem będzie sprawdzenie poprawności otrzymanego polecenia. Stan obiektu nie będzie zmieniany - zadaniem będzie wyłącznie dokonanie sprawdzenia!

I teraz mam pytanie:

Czy takie wywołania będą "bezpieczne"? Czy też może się wątki mogą wzajemnie zakłócać zwracane wyniki? Powinienem użyć jakiś mechanizmów zabezpieczających (blokujących) - czy w tej sytuacji nie jest to konieczne?

Nie do końca wiem jak domyślnie zachowuje się system przy takich wywołaniach: czy tworzy kopię funkcji dla każdego wywołania, czy kolejkuje te wywołania, czy też możliwe są nadpisania parametrów funkcji i nieprzewidywalne wyniki...

Zdaje sobie sprawę, że to pytanie jest jakieś takie... no ale cóż.

Pozdrawiam i z góry dzięki za pomoc

0

jak wykonujesz tylko odczyt na tej zmiennej globalnej to nie musisz się niczym przejmować, to chyba logiczne!
Jedyny problem może być wtedy, gdy choćby jeden wątek w tym czasie próbował coś zmienić w tej zmiennej.

Dla pewności uczyniłbym tą zmienną stałą, a w konstruktorze ustawił jej wartość (wtedy będzie wszystko jasne i bezpieczne).

0

Otóż ciekawi taka sytuacja, że oto prawie równocześnie 2 wątki wywołują tą funkcję

int CommandMap::checkCommand(int iLevel, string sCmd);

np.
1.

myProtocol.checkCommand(1, "Start");
myProtocol.checkCommand(2, "End");

Jak to się wykona? Dla każdego wywołania będzie zrobiona kopia funkcji w pamięci, czy może będzie to jakoś kolejkowane?

Czy możliwe jest, że wystartuje jeden wątek - zostanie przerwany - ruszy drugi wątek, tak że nadpisze pamięć w miejscach gdzie sa zmienne iLevel i sCommand także dla obydwu wywołań: iLevel=2 i sCommand="End". Skutkiem czego obydwa zwrócą ten sam rezultat.

Wydaje mi się, że nie jest to możliwe, ale właśnie do końca nie wiem jak to się wykona w takiej sytuacji.

0

Dla każdego wywołania będzie zrobiona kopia funkcji w pamięci, czy może będzie to jakoś kolejkowane?

Żadna tam kopia. Każdy wątek ma własny stos, który wykorzystywany jest do przekazywania parametrów funkcji i przechowywania zmiennych lokalnych.

Powinienem użyć jakiś mechanizmów zabezpieczających (blokujących) - czy w tej sytuacji nie jest to konieczne?

Jeśli może zajść sytuacja, że jeden wątek zmienia stan obiektu, podczas gdy drugi w tym samym czasie z niego coś czyta, a zmiana stanu ma istotny wpływ na proces/wynik odczytu, musisz synchronizować, nie ma innej opcji.

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