[C++] plusieurs thread et std::cin

Résolu/Fermé
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 - 20 juin 2008 à 09:59
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 - 20 juin 2008 à 17:10
Bonjour,
j'ai comme petit projet de faire un petit chat (histoire de mieux maitriser réseau et thread).
Si je lance plusieurs thread avec dans chacun d'eux une ligne de saisi :
std::cin>>a; Est-ce que tout les thread récupèrerons cette variable, ou seulement un seul ?
Pour illustrer un peu mieux le propos, un petit programme "test"
int main(){
    User A,B;
    thread(envoi,A);// lance un thread avec comme fonction "envoi" et comme parametre "A"
    thread(envoie B);
    ...
    return 0;
}
void* envoi(User A);
{
    std::string a;
    while(1){
        std::cin>>a;
        A.envoi(a);// méthode envoyant un string à l'utilisateur A
        }
}

Donc, lorsque je lancerai ce programme je taperai une ligne de caractère dans la console, est-ce que le message ainsi tapé sera envoyé à A et B ou seulement à l'un des deux ?

3 réponses

kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527
20 juin 2008 à 13:23
C'est à vérifier mais je suis à peu prêt sûr qu'il ne sera envoyé qu'à l'un des deux....

Moi je le vois comme ça:
stdin est un fichier. Si tu avais ouvert un fichier "fich" et donné le même descripteur de fichier à un thread A et un thread B, si l'un des deux lit, alors le pointeur de fichier avance de n octets lus, et ça se repercute chez A et B car il partagent le même descripteur de fichier.
Je pense que dans ton cas ça fonctionne pareil.

Un autre exemple: si un programme faisait ça:
cin >> a;
cin >> a;

C'est l'équivalent de 2 threads qui feraient juste une fois
cin >>a;

Sauf que dans le cas des threads, on ne sait pas qui arrivera le premier à moins de les synchroniser.
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
20 juin 2008 à 14:23
Merci Kilian, ton raisonnement me plaît bien.
Du coup, ça complexifie un peu la gestion du bazard, il faut une espèce d'ordonanceur général.
Je vais revoir tout mon schéma de programme...
0
kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527
20 juin 2008 à 14:41
Globalement, l'utilisation des threads implique toujours de synchroniser leur accés à des ressources critiques. Par ressources critiques, j'entends les ressources partagées comme par exemple une variable globale, un descripteur de fichier partagé (comme cin) etc...

Prenons un exemple avec une variabl partagée int a;
Avec une procédure de thread qui donne ça:
void inc(int *a)
{
    *a = (*a) + 1;
}

Si tu lances deux threads A et B qui font cette même procédure, voici ce qui risque d'arriver: A se lance en premier, il récupère la valeur dans l'adresse a qui est 6. Et hop ton système d'exploitation décide soudain que c'est au tour de B de s'excuter, il arrive dans la procédure, regarde ce qu'il y a dans *a, il y a 6, il fait +1 et affecte 7 dans dans *a. Hop le système d'exploitation interrompt B et relance A qui va incrémenter l'ancienne valeur qu'il avait testé qui est 6, et l'incrémenter de 1, il va mettre 7 dans *a.

Mais si l'ordonnaceur en avait décidé autrement tu aurais pu te retrouver avec 8 dans *a à la fin.
Voilà le soucis avec des codes qui s'executent en parallèle et qui manipulent des données partagées.
L'idéal est d'utiliser des mutex pour contrôler tout ça. Il existe aussi un jeu de fonction sous windows : EnterCriticalSection et LeaveCriticalSection.
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297 > kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016
20 juin 2008 à 15:23
Merci pour la précision.
Mais je ne vais pas aller jusque là. En effet, je n'utilise dans les thread que des variables globales en lecture.
Ce qu'il faudrait faire dans mon cas, c'est faire une espèce de signal "lire donée en variable et envoyer".
Ou alors ce que je fait :
envoi(User* V)
{
while(1)
{
std::cin>>a;
for(int i=0;V[i]!=0;++i)
V[i].envoi(a);
}
}

L'histoire de mutex arrivera en revanche dans le sens retour : si A et B m'envoient un message, ils risquent d'arriver dans le désordre (mais à la rigueur ce n'est pas grave) ou pire d'arriver mélanger.
0
kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527 > Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023
20 juin 2008 à 15:29
Là l'usage des files de message me semblerait ce qu'il y a de mieux. Mais c'est sous Linux/Unix. Tu utilises quoi comme Os hôte pour ton programme?
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297 > Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023
20 juin 2008 à 17:10
Linux ET windows. Mais dans un premier temps, je vais courir le risque d'avoir un problème de mélange, ce qui n'est pas aussi grave qu'un message pas envoyer ou pas reçu du tout.
0
mich62120 Messages postés 631 Date d'inscription jeudi 22 novembre 2007 Statut Membre Dernière intervention 21 janvier 2010 6
20 juin 2008 à 14:49
Salut,

Une question pour toi kilian.
Ca ne serait pas dans ce cas la qu'il faut utiliser les mutex?
Je voudrai savoir car je suis en train de faire une application C# qui se lance plusieurs et qui partage un fichier texte pour écriture et lecture.J'essaye de me rensigner sur les mutex mais j'ai du mal à les cerner.C'est à peu près le même problème non?
Mich
0
kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527
20 juin 2008 à 15:11
Tout à fait dans ton cas tu auras vraiment besoin de mutex pour un partage de fichiers.
Si tu as des procédures qui écrivent dans le fichier, et d'autres qui lisent dedans, tu peux même implémenter le modèle des lecteurs et rédacteurs.
https://fr.wikipedia.org/wiki/Probl%C3%A8me_des_lecteurs_et_des_r%C3%A9dacteurs
0
mich62120 Messages postés 631 Date d'inscription jeudi 22 novembre 2007 Statut Membre Dernière intervention 21 janvier 2010 6 > kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016
20 juin 2008 à 15:22
Merci du renseignement.

J'ai une version sans mutex du programme est ce que je peus l'implanter dedans ou je dois tout reprendre à zéro?

Mich
0
kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527 > mich62120 Messages postés 631 Date d'inscription jeudi 22 novembre 2007 Statut Membre Dernière intervention 21 janvier 2010
20 juin 2008 à 15:25
Noon, ya juste à rajouter les mutex :-)
0
mich62120 Messages postés 631 Date d'inscription jeudi 22 novembre 2007 Statut Membre Dernière intervention 21 janvier 2010 6 > kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016
20 juin 2008 à 15:28
ok merci bien kilian.
0