• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Problem z wielowątkowością C++

Object Storage Arubacloud
0 głosów
348 wizyt
pytanie zadane 21 lutego 2021 w C i C++ przez Drożdżówka Obywatel (1,870 p.)

Witam.

Mam taki problem, stworzyłem w programie taką funkcję readKey(), które odczytuje w tle wciśnięty klawisz, tak wygląda jej kod:

void readKey() {
	
	while (true) {
		pressedKey = ' ';
		pressedKey = _getch();
		Sleep(16);

	}
}

...i teraz pojawia się problem, w drugiej funkcji po naciśnięciu "w", lub "s" program zachowuje się jakbym nacisnął któryś z tych klawiszów 3 razy.

void mainMenu() {
	static int cursorPos = 3;

	system("cls");

	while (true) {
		clearScreen();
		showConsoleCursor(false);

		for (int i = 23; i > 0; i--) {
			cout << "\n";

		}

		setFontColor("white");  cout << "______________________________________________________________________________________________________________________\n";
		setFontColor("green"); cout << "linia1\n";
		if (cursorPos == 3) { setFontColor("yellow"); } else { setFontColor("white"); } cout << "linia2\n";
		if (cursorPos == 2) { setFontColor("yellow"); } else { setFontColor("white"); } cout << "linia3\n";
		if (cursorPos == 1) { setFontColor("yellow"); } else { setFontColor("white"); } cout << "linia4\n";

		switch (pressedKey) {
		case 'w': if (cursorPos == 3) { cursorPos = 1; }
				else { cursorPos++; } break;
		case 's': if (cursorPos == 1) { cursorPos = 3; }
				else { cursorPos--; } break;
		default: break;

		}
	}
}

Na początku programu oczywiście odpalam dwa wątki z tymi funkcjami.

Dlaczego tak się dzieje? Wprowadziłem opóźnienie w postaci Sleep(), aby program nie zamieniał od razu char'a na ' ' i nadal nic :(

 

 

Z góry dziękuję za pomoc!

1 odpowiedź

+1 głos
odpowiedź 22 lutego 2021 przez TOM_CPP Pasjonat (22,640 p.)
wybrane 22 lutego 2021 przez Drożdżówka
 
Najlepsza

Programowanie wielowątkowe jest trudne i nieintuicyjne. W Twoim przypadku w czasie kiedy realizowana jest funkcja sleep, główny wątek odczytuje wartość zmiennej pressedKey ( w instrukcji switch ) 3 razy, gdybyś wydłużył czas oczekiwania, to zmienna ta była by odczytywana większą liczbę razy. Kluczem to rozwiązania jest zerowanie ( przypisanie do niej spacji ) zmiennej pressedKey w głównym wątku. Dodatkowo skorzystałbym w tym przypadku z std::atomic

void readKey() {
std::atomic<char> pressedKey;   
    while (true) {
        pressedKey.store(_getch()); 
    }
}

oraz

void mainMenu() {
    static int cursorPos = 3;
 
    system("cls");
 
    while (true) {
        clearScreen();
        showConsoleCursor(false);
 
        for (int i = 23; i > 0; i--) {
            cout << "\n";
 
        }
 
        setFontColor("white");  cout << "______________________________________________________________________________________________________________________\n";
        setFontColor("green"); cout << "linia1\n";
        if (cursorPos == 3) { setFontColor("yellow"); } else { setFontColor("white"); } cout << "linia2\n";
        if (cursorPos == 2) { setFontColor("yellow"); } else { setFontColor("white"); } cout << "linia3\n";
        if (cursorPos == 1) { setFontColor("yellow"); } else { setFontColor("white"); } cout << "linia4\n";
 
        switch (pressedKey.load()) {
        case 'w': if (cursorPos == 3) { cursorPos = 1;  }
                else { cursorPos++; }; pressedKey.store(' '); break;
        case 's': if (cursorPos == 1) { cursorPos = 3;  }
                else { cursorPos--; }; pressedKey.store(' '); break;
        default: break;
 
        }
    }
}

 

komentarz 22 lutego 2021 przez j23 Mędrzec (194,920 p.)

W sumie można by dać:

switch (pressedKey.exchange(' '))

Wtedy nie trzeba wywoływać store.

komentarz 22 lutego 2021 przez mokrowski Mędrzec (155,460 p.)
switch (pressedKey.exchange('\0', std::memory_order_release))

IMHO lepiej wyzerować tę zmienną. Spacja może w przyszłości być atrakcyjna.

Tak czy siak, bez większej ilości kodu nie będzie łatwo doradzić. Np. po co pętlić jeśli można obudzić się w reakcji na zmianę wciśniętego klawisza.

komentarz 22 lutego 2021 przez Drożdżówka Obywatel (1,870 p.)
Można wiedzieć z jakiej biblioteki są te funkcje?
komentarz 22 lutego 2021 przez mokrowski Mędrzec (155,460 p.)
<atomic>

Podobne pytania

0 głosów
1 odpowiedź 380 wizyt
pytanie zadane 27 czerwca 2020 w C i C++ przez Drożdżówka Obywatel (1,870 p.)
0 głosów
2 odpowiedzi 430 wizyt
0 głosów
1 odpowiedź 515 wizyt
pytanie zadane 7 stycznia 2021 w C i C++ przez Bartek030 Obywatel (1,460 p.)

92,536 zapytań

141,377 odpowiedzi

319,456 komentarzy

61,922 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...