IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Gestion concurrence UPDATE - API MySQL C


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2017
    Messages : 11
    Points : 9
    Points
    9
    Par défaut Gestion concurrence UPDATE - API MySQL C
    Bonjour à tous,

    Je vous explique le problème actuel :
    J'ai une table de forçage et une table de calcul. Lorsque l'utilisateur ne souhaite aucun forçage de variables, la table de calcul se charge d'actualiser la BD. Si un forçage est demandé sur une variable spécifique alors la table de forçage prend la main sur l'actualisation de la variable dans la BD et la table de calcul n'a plus d'action sur cette variable mais sur toutes les autres oui jusqu'à ce que la table de forçage prenne la main dessus.
    Je souhaitais mettre en place une gestion telle que celle-ci à l'aide de mutex étant donné que chaque variable devienne une section critique. Cependant, si j'ai 1 000 variables j'aurai donc 1 000 mutex ce qui, selon moi, n'est pas viable. Je pense donc que mon raisonnement est erroné.
    Je m'en remets à vous afin de m'éclaircir sur les solutions qui s'offrent à moi, vos recommandations ou alors votre approbation de cette gestion par mutex.

    En vous remerciant par avance,

    Cordialement,
    esc39

    PS : J'utilise l'API MySQL C et je suis sur Windows.

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    Pourrais-tu nous décrire plus largement ce que tu souhaites ? Cela nous permettra de mieux comprendre ce que tu souhaites faire et de te proposer une bonne solution.

    A priori, je trouve tes termes très bizarre :
    - une table de forçage : toute table est une table de forçage non ? (sauf celles en lecture seule)
    - une table de calcul qui fait des MàJ des données : elle fait du forçage alors aussi ?
    - variables : étonnant de parler de variables, qu'on utilise souvent dans du code ; ce n'est pas un terme souvent utilisé pour une BDD qui contient des données (qui peuvent être variables). Cela donne la sensation que tu stockes des données temporaires, intermédiaires, dans ta BDD.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2017
    Messages : 11
    Points : 9
    Points
    9
    Par défaut
    Bonjour,

    Oui désolé je suis débutant en base de données. Alors :
    J'ai un thread qui calcule des variables en fonction des données présentes dans la BD. Ces variables sont ensuite mis à jour dans la BD (ce sont désormais des données mais dans mon programme se sont des variables). Ceci s’exécutant en continu.
    Un second thread est exécuté. Il correspond à la table de forcage (pour moi table peut être seulement une table de visualisation des données de la BD, ici on peut forcer l'écriture d'une donnée dans la BD). Lorsque l'utilisateur souhaite forcer une donnée, le calcul de cette donnée ne serra pas faite dans la thread 1 mais celle mis à jour sera celle fournit dans la table de forcage.
    J'espère que je me suis fait comprendre.

    J'ai pensé à une solution dites-moi ce que vous en pensez :
    Ajout pour chaque ligne d'une donnée "flag_forcage". Lorsque l'utilisateur ne force pas une donnée alors ce flag est à 0 sinon il est à 1. Dans le thread 1, je mets une condition : si flag à 0 alors calcule puis mise à jour dans BD sinon ne rien faire. Et dans le thread 2, si flag à 1 alors mise à jour avec valeur donnée par l'utilisateur sinon ne rien faire.
    Qu'en pensez-vous ?

    Cordialement,
    esc39

  4. #4
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Donc, le problème, c'est que tu as deux threads, qui dépendent l'un de l'autre sans y être attentifs.

    Une base de données est un conteneur de données. Son seul rôle est de permettre d'accéder à ces données, en lecture ou en écriture.

    Ton programme, lui, utilise la base de données.

    Visiblement, tu as plusieurs ensemble de données, pas forcément compatible.
    il y a au moins:
    • source officielle: les données trouvées dans la base de donnée avant le calcul
    • source utilisateur: les éventuels forçages qu'il a choisit
    • source pratique: les données que le programme doit utiliser pour calculer
    • résultat: les données obtenues après le calcul.

    Concrêtement, la source pratique est obtenue en prenant d'abord toutes les données officielles, puis en remplaçant toutes celles définies dans la source utilisateur par ces valeurs-là.

    Parmi les questions que tu te poses, il y a visiblement "comment faire pour que le calcul travaille sur cette source pratique?".
    Celles que je me poses moi, en voyant ton message, sont:
    1. Pourquoi avoir deux threads pour accomplir une tache?
    2. Pourquoi avoir partagé le travail en deux sous-taches non indépendantes?
    3. Pourquoi le thread de calcul fait une partie du chargement des données?
    4. Est-ce que la mise à jour de la base de données se fait si une partie des données vient de forçages?
    5. Est-ce que les données dans la base sont uniques ou séquencielles? (dernière température ou températures à chaque instant)
    6. La base contient-elles uniquement des résultats ou non?


    Les threads sont un moyen de gagner en performance, s'ils sont utilisés correctement. C'est un moyen de tout rater dans tout autre cas, car ils désynchronisent l'exécution.

    Tu as visiblement un ordre à respecter pour charger les données (d'abord depuis la base, puis les forçages), il n'y a aucune raison de les faire simultanément.
    Le calcul ne peut pas se faire tant que les données ne sont pas chargées.

    Les dernières questions sont plus inquiétantes, mais peut-être bégnines. Cela dépend de si les données lues et écrites en base sont disjointes, et surtout de si les données écrites ne sont pas exclusives (elles sont datés, ou numérotées?).

    Petit exemple:
    Supposons que ton calcul soit un calcul de facture.
    ta base contiendrait a priori les informations suivantes:
    une liste d'articles avec leur prix et taux de tva applicable
    une liste de commandes, chacune avec une liste de produits achetés, et leurs quantités respectives, et le prix total (pas forcément renseigné)

    Le calcul fait par le programme serait le prix totale d'une facture précise.
    Les données à charger serait la liste des articles de cette facture, et la liste des descriptions d'articles (correspondant à cette facture?)
    le calcul est fait, et l'insertion est mis dans la base, pour ne pas avoir à le recalculer.

    Si l'utilisateur fait un forçage du prix d'un article, le prix calculé est une jolie simulation, mais ne doit pas être mis dans la base, puisqu'il ne correspond pas aux données qui s'y trouve.
    A moins que le total soit justement le prix effectivement payé, et qu'il s'agisse du moyen d'appliquer des réductions arbitraires.

    Réfléchis bien à l'intérêt de la donnée produite, vis à vis de la base.
    Réfléchis aussi à voir si la base ne saurait pas le calculer.


    Donnes nous un peu plus de détails concrets: quelques nature de données, un exemple de forçage possible, le calcul (éventuellement simplifié), les méta-données insérées en base, etc.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2017
    Messages : 11
    Points : 9
    Points
    9
    Par défaut
    Merci beaucoup c'est très explicite et très applicable à ce que je recherche. Pour que vous compreniez pourquoi séparer la table de forcage du calcul des données il faut que je vous explique exactement en quoi ca consiste.
    Il y a deux applications et deux types de données dans la BD (Entrées & Sorties). L'application 1 se charge de consommer les données Entrées à l'instant n puis, injecte les Sorties calculées à partir des Entrées à l'instant n. L'application 2 s'occupe de consommer les données Sorties de l'instant n puis, injecte les donnés Entrées n+1 calculées à partir des Entrées et des Sorties à l'instant n. Puis ca reboucle etc. Lorsque l'application 1 a fini l'injection des données Sorties dans la BD, un message est envoyé à l'application 2 pour synchronises les tâches.
    Application 2 = calcul + forcage

    Maintenant que le projet est présenté les questions :
    1) Pourquoi deux threads ?
    Après réflexion, il n'y a pas tellement d'intérêt (initialement, je voulais que lorsque l'utilisateur force une donnée que la requête soit immédiate et que la tâche n'attende pas le message de l'application 1. Or, ceci est absurde car la donnée ne sera traitée qu'une fois que l'application 2 aura envoyé un message à l'application 1 d'aller chercher les données Entrées. Finalement, tu as raison 1 thread qui s'exécute pour les deux opérations après réception du message de l'application 1 est "logique".

    2) Les données ne sont pas historisées donc si on se trouve dans le cas après le calcul/forcage par l'application 2, les Entrées sont à l'instant n+1 et les Sorties à l'instant n.

    Cordialement,
    esc39

  6. #6
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Donc, si je comprends bien, tu as deux applications indépendantes, qui communiquent via une base de donnée?

    En SQL, il existe quelque chose d'intéressant qu'on appelle une transaction.
    Ce mécanisme permet de grouper des requêtes de façon à ce qu'elle soit toute réussies ou annulées en même temps.

    Les autres requetes ne peuvent percevoir que les données comme si elles étaient avant la transaction (même si une partie de celle-ci est en cours), et ce jusqu'à la fin de la transaction.
    Mieux, la transaction posant des verrous, il n'est pas possible de modifier les données qu'une transaction modifie.

    Du coup, tu n'as même plus vraiment besoin d'un mécanisme de communication entre les applications.

    Mathématiquement parlant, tu as trois fonctions du temps (des suites, puisque le temps est discret, dans ton cas)
    • entrées(t)
    • sortie(t)
    • forçage(t)

    Tu as aussi les propriétés suivantes:
    • sortie(t) = application1(entree(t))
    • entre(t+1) = application2(sortie(t), forçage(t+1))


    Actuellement, tu as deux fonctions main():
    programme1() {
      while (fin du temps?) {
        attendre que les entrées soient prêtes
        les lire dans la base de données
        calculer les nouvelles sorties
        les écrire dans la base de données
        signaler que les sorties sont prêtes
      }
    }
    programme2() {
      while (fin du temps?) {
        attendre que les sorties soient prêtes
        les lire dans la base de données
        lire les forçages
        calculer les nouvelles entrées
        les ecrire dans la base de données
        signaler que les entrées sont prêtes
      }
    }
    A part l'inversion des mots "sorties" et "entrées", les programmes sont structurellement identiques. Surtout si on considère les forçages comme une entrée.

    Imagines que tu places dans la base deux données particulières: les timestamp d'écriture des entrées et des sorties.
    Alors la partie "attendre" serait simplement une boucle où tu vérifies si la date de création des données utilisées est plus récentes que la date de la dernière utilisation.

    Par ailleurs, en ne faisant qu'un seul programme, ca pourrait être plus souple:
    programme1() {
      lire les entrées dans la base
      while (fin du temps?) {
        lire les forçages
        calculer les nouvelles entrées
        calculer les nouvelles sorties
        les écrire dans la base de données
      }
    }
    Ca demandera certainement un ajustement pour la détermination des conditions initiales, mais c'est l'idée générale.
    Ta base ne sert alors plus que de support d'information externe.

    Une base de donnée reste plus lente qu'un simple fichier, et encore plus que la mémoire vive.
    Si tu ne conserve pas d'historique des données, alors c'est plus lent qu'un fichier écrit à la fin de l'exécution du programme, pour un résultat identique.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2017
    Messages : 11
    Points : 9
    Points
    9
    Par défaut
    Merci beaucoup.
    Je suis d'accord avec toi concernant les transactions (je ne savais pas que ca existait) mais est-ce vraiment bon de soliciter la BD en "continu" ? Ne vaut-il pas mieux gérer une comm de telle manière à alléger la BD ?
    Autre question, existe t'il des triggers sur un type de donnée de tel manière à envoyer un signal de la BD vers l'application pour lui dire comme quoi une valeur a été changé ? (une gestion d'interruption de la BD).
    Vaut-il mieux envoyer 5 requêtes d'écritures ou 1 requête avec toutes les données ? (= la BD gère t'elle les requêtes en parallèle ?)

    Je ne peux pas regrouper les applications car derrière l'application 1, la donnée est envoyée vers un équipement et c'est une contrainte du projet (2 applications).
    Merci d'avance,

    Cordialement,
    esc39

Discussions similaires

  1. Api mysql avec Devc++, erreur de compilation
    Par Viiince dans le forum Autres éditeurs
    Réponses: 5
    Dernier message: 15/06/2004, 17h19
  2. [MFC] [API mySQL] Sous requêtes
    Par Guybrush113 dans le forum MFC
    Réponses: 5
    Dernier message: 29/04/2004, 16h14
  3. API MySQL - Connexion réseau
    Par klael dans le forum Bases de données
    Réponses: 3
    Dernier message: 18/03/2004, 09h25
  4. Utilisation des API MySQL // ADO ou BDE ? (sujet 2)
    Par rohstev dans le forum C++Builder
    Réponses: 8
    Dernier message: 07/11/2003, 10h50
  5. [DevC++]Installation de l'API MySQL
    Par Nasky dans le forum Dev-C++
    Réponses: 22
    Dernier message: 24/07/2003, 22h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo