je créer un sujet pour un problème assez particulier, j'ai débuté le c++ en autodidacte il y a un petit moment avec le site openclassroom mais j'ai pu constaté que je dois réapprendre pas mal de choses par rapport au contenu du site qui me semble un peu dépassé... Notamment là j'ai besoin d'en apprendre plus sur les threads (qui n'est pas au menu du cours sauf erreur de ma part), pour résumer la situation, je code un jeu en sfml avec un map interactive.
J'ai un main dans lequel je déclare une tilemap, vers la fin du main je fais appel à une fonction membre de ma classe tilemap, à savoir drawingEngine.
Dans cette fonction membre je déclare un thread de la fonction suivante
La fonction floodFill est une fonction disponible dans ma classe tilemap :
vector<int> TileMap::floodFill(int x, int y, int* tiles, vector<int>& vctr)
{
if(tiles[x + y * m_width] == 0)
{
vctr.push_back(x + y * m_width);
floodFill((x+1), y, tiles, vctr);
floodFill(x, (y+1), tiles, vctr);
floodFill((x-1), y, tiles, vctr);
floodFill(x, (y-1), tiles, vctr);
}
return vctr;
}
Malheuresement, c'est ce qui m'amène ici, j'ai une erreur de compilation et j'arrive pas à comprendre mon erreur parce que je suis pas assez documenté sur le sujet, ce qui m'amène à vous demander deux choses.
La première, est-ce que vous auriez un site à me conseiller qui explique bien en détail les threads (anglais/français/japonais ya pas de soucis) ? La deuxième, est-ce que vous pourriez me dire ce qui ne marche pas dans mon code ?
Désolé je suis pas habitué à poster ici je suis pas encore familier avec toutes les règles désolé si je fais une bourde et merci d'avance pour ceux qui veulent bien m'aider
Basiquement un thread est une fonction qui va s'executer en parallele de ton code principal.
Par contre la parallellisation vient avec un côut processeur non négligeable, et des contraintes d'accessibilité des variables: Tu dois t'assurer que les variables communes à ton thread et le programme principale ne sont pas accédées en même temps, sinon cela produit des resultat imprévisibles (undefined behavior, ou UB), les mutex sont la pour gérer cette problematique.
Concernant ton code, je ne suis pas convaincu que les appels récursifs vont avoir l'effet escomptés:
if(tiles[x + y * m_width] == 0) // donc x et y sont a zéro ?
{
vctr.push_back(x + y * m_width);
floodFill((x+1), y, tiles, vctr); // n'ajoute rien, x+1 est different de zero
floodFill(x, (y+1), tiles, vctr); // n'ajoute rien, y+1 est different de zero.
floodFill((x-1), y, tiles, vctr); // n'ajoute rien, x-1 est different de zero.
floodFill(x, (y-1), tiles, vctr); // n'ajoute rien, y-1 est different de zero.
}
Inutile de retourner vctr vu qu'il est passé par référence non constante. Il sert a quoi tiles ?
Malheuresement, c'est ce qui m'amène ici, j'ai une erreur de compilation et j'arrive pas à comprendre mon erreur parce que je suis pas assez documenté sur le sujet, ce qui m'amène à vous demander deux choses.
[...]
Désolé je suis pas habitué à poster ici je suis pas encore familier avec toutes les règles désolé si je fais une bourde et merci d'avance pour ceux qui veulent bien m'aider
Bonne habitude à prendre pour poster : donner le message d'erreur parce que l'on a pas tout ton code sous la main donc on ne va pas pouvoir deviner le message. Au pifomètre je dirais que c'est la référence qui pèche dans le cas d'un passage à un thread.
Sinon la vraie question : es tu sûr d'avoir besoin de multithreading ?
remière chose, j'avais zappé le message d'erreur, il est là, par contre il est énorme
C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\functional||In instantiation of 'struct std::_Bind_check_arity<std::vector<int> (TileMap::*)(int, int, int*, std::vector<int>&), int&, int&, int*&, std::reference_wrapper<std::vector<int, std::allocator<int> > > >':| C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\functional|1538|required from 'struct std::_Bind_simple_helper<std::vector<int> (TileMap::*)(int, int, int*, std::vector<int>&), int&, int&, int*&, std::reference_wrapper<std::vector<int, std::allocator<int> > > >'| C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\functional|1552| required by substitution of 'template<class _Callable, class ... _Args> typename std::_Bind_simple_helper<_Func, _BoundArgs>::__type std::__bind_simple(_Callable&&, _Args&& ...) [with _Callable = std::vector<int> (TileMap::*)(int, int, int*, std::vector<int>&); _Args = {int&, int&, int*&, std::reference_wrapper<std::vector<int, std::allocator<int> > >}]'| C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\thread|142|required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = std::vector<int> (TileMap::*)(int, int, int*, std::vector<int>&); _Args = {int&, int&, int*&, std::reference_wrapper<std::vector<int, std::allocator<int> > >}]'| D:\Programmation\C++\Game\TileMap.cpp|227|required from here| C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\functional|1426|error: static assertion failed: Wrong number of arguments for pointer-to-member| C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\functional||In instantiation of 'struct std::_Bind_simple<std::_Mem_fn<std::vector<int> (TileMap::*)(int, int, int*, std::vector<int>&)>(int, int, int*, std::reference_wrapper<std::vector<int> >)>':| C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\thread|142|required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = std::vector<int> (TileMap::*)(int, int, int*, std::vector<int>&); _Args = {int&, int&, int*&, std::reference_wrapper<std::vector<int, std::allocator<int> > >}]'| D:\Programmation\C++\Game\TileMap.cpp|227|required from here| C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\functional|1505|error: no type named 'type' in 'class std::result_of<std::_Mem_fn<std::vector<int> (TileMap::*)(int, int, int*, std::vector<int>&)>(int, int, int*, std::reference_wrapper<std::vector<int> >)>'| C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\functional|1526|error: no type named 'type' in 'class std::result_of<std::_Mem_fn<std::vector<int> (TileMap::*)(int, int, int*, std::vector<int>&)>(int, int, int*, std::reference_wrapper<std::vector<int> >)>'|
Deedolith, je vais check les mutex dès aujourd'hui. Pour la ligne
if(tiles[x + y * m_width] == 0)
En fait c'est une tilemap, ma map est un tableau de int et cette ligne me permet de vérifier si la valeur de la tile est égale à zéro Pour le return bien vu, je viens d'apprendre std::ref() mais j'avais pas encore changé ça :s
Avec un pointeur de fonction membre, il faut une instance. Où est l'instance de TileMap dans la construction du thread ? (Voir la cppreference.com pour sont utilisation). Seconde chose, pourquoi floodFill est une fonction membre non statique alors qu'elle ne fait aucunement référence à ses membres ?
Je trouve ta fonction particulièrement étrange, pour moi il y a une boucle infinie.
Au passage, tu n'as pas répondu à la question de Ksass'Peuk: es tu sûr d'avoir besoin de multithreading ?
Pour l'instance de TileMap, c'est une question que je me posais, la déclaration du thread se trouve dans une fonction membre, du coup je ne peux pas déclarer l'instance :s
Maintenant pour les fonctions statiques/non statiques, c'est parce que je ne suis pas encore arriver là, il me reste deux chapitres, quelque chose comme ça à propos de la POO
La boucle n'est pas infinie puisque la fonction va à un moment donné rencontrer une tile dont la valeur n'est pas 0.
Ah désolé pour l'oubli, alors j'en ai besoin parce que j'utilise la librairie SFML pour coder un petit jeu et c'est nécessaire pour que je continue à rafraîchir ma fenêtre :/
Ce qui a diminué le message d'erreur lors de la compilation
||=== Build: Debug in Game (compiler: GNU GCC Compiler) ===| C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\functional||In instantiation of 'struct std::_Bind_simple<std::vector<int>()>':| C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\thread|142|required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = std::vector<int>; _Args = {}]'| D:\Programmation\C++\Game\TileMap.cpp|228|required from here| C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\functional|1505|error: no type named 'type' in 'class std::result_of<std::vector<int>()>'| C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\functional|1526|error: no type named 'type' in 'class std::result_of<std::vector<int>()>'| ||=== Build failed: 2 error(s), 3 warning(s) (0 minute(s), 0 second(s)) ===|
Ah désolé pour l'oubli, alors j'en ai besoin parce que j'utilise la librairie SFML pour coder un petit jeu et c'est nécessaire pour que je continue à rafraîchir ma fenêtre :/
Non ce n'est pas nécessaire . Il est peu probable que ton ordinateur ne soit pas assez rapide pour faire :
Je te déconseille de partir sur du multithreading. Le résultat obtenu risque d'être décevant car ton programme risque de se finir beaucoup plus vite que prévu. Ta grille (ou peu importe la zone que tu essaies de remplir) va se remplir en un temps assez court et surtout tu ne pourras pas contrôler ce temps.
Personnellement, je te conseille de partir sur la deuxième solution que t'as proposé Laurent (le créateur de la SFML, au passage ), c'est à dire de coder ta fonction floodFill() de façon à ce que tu puisses avancer le remplissage par incréments. A mon avis, ça serait beaucoup plus simple (bien que moins élégant), d'oublier la récursivité pour ce cas là.
Je sais pas sûr d'avoir été très clair, hésite pas à demander si t'as pas compris
Franchement, le multithreading dans un jeux est entre autre utilisé pour présenter à l'utilisateur un joli écran animé (bar de progression par exemple) pour faire patienter pendant le chargement des (très) nombreuses ressources (fonts / textures / modeles 3D ect ….)
Dans le cadre d'un "petit" jeux où les ressources sont peut nombreuses, le temps de chargement de ces dernières n'est pas important (voir négligeable), donc la necessité d'un ecran de chargement est caduque.
Fait d'abord sans, occupe toi du jeux en lui même, le chargement des ressources pourra toujours être amélioré plus tard.
PS: using namespace, c'est le MAAAAAAALLLLL (je suis sûr que tu l'as utilisé).
D'accord je vais essayer de faire comme au pire je reviens vers toi par mp si j'ai un soucis Raynobrak
Ah d'accord c'est compris pour le multithreading
Pour le using namespace, je l'utilise parce que c'était dans le cours openclassroom, je me rends compte petit à petit qu'il a l'air bien désuet et que pas mal de monde le pointe du doigt Du coup c'est quoi le soucis avec using namespace ?
Pour le using namespace, je l'utilise parce que c'était dans le cours openclassroom, je me rends compte petit à petit (1) qu'il a l'air bien désuet et que pas mal de monde le pointe du doigt. (2) Du coup c'est quoi le soucis avec using namespace ?
(1) Il était même déjà pas franchement glorieux quand il était pas encore obsolète. L'obsolescence de ce cours c'est la partie émergée de l'iceberg. Il y a quasiment tout qui va pas dedans.
Ah d'accord, j'aurais peut être dû apprendre le c++ ailleurs finalement
- Edité par ZeonSoldier 16 mai 2019 à 12:53:56
Thread dans une classe, fonction membre et arg
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C