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

Threads & Processus C++ Discussion :

accès concurrent en ecriture a un vecteur


Sujet :

Threads & Processus C++

  1. #1
    Membre habitué
    Inscrit en
    Mai 2013
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 8
    Par défaut accès concurrent en ecriture a un vecteur
    Bonojur tout le monde

    J'ai une question sur l’accès concurrent en ecriture a un vecteur:
    esque on peut faire un puchback sur un vecteur en même temps avec plusieurs threads?
    ou bien on doit utiliser les mutex.

    Merci d'avance

  2. #2
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Par défaut
    push_back comme toute la bibliothèque standard C++ n'est pas "thread-safe".
    Il te faudra en effet utiliser un mutex pour cette opération.

    Tu peux peut-être repenser ton algorithme pour éviter un accès concurrent. Par exemple :
    - un vector par thread
    - le vecteur fait la bonne taille dès le départ et les threads accèdent à des cases différentes

  3. #3
    Membre habitué
    Inscrit en
    Mai 2013
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Mai 2013
    Messages : 8
    Par défaut
    Ce que je trouve anormal c'est que j'ai utilisé 10 threads qui accède au même vecteur pour ajouter des case de données avec puch_back sans mutex pour l'instant y'a aucun problème.

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Salut,
    Citation Envoyé par piet1 Voir le message
    Ce que je trouve anormal c'est que j'ai utilisé 10 threads qui accède au même vecteur pour ajouter des case de données avec puch_back sans mutex pour l'instant y'a aucun problème.
    C'est juste une question de chance...

    "Parce que tu as la chance" que les threads ont sans doute mis un peu de temps à se lancer, ou celle que les différents threads ont des durées d'exécutions différentes avant d'arriver au push_back, tu "as la chance" que les push_back s'effectuent correctement.

    Seulement, si tu as "un peu moins de chance", tu risques tout aussi bien de te retrouver dans une situation où push_back finira par faire du grand n'importe quoi (il faut se rappeler que push_back est responsable de l'augmentation du nombre d'éléments contigus présent en mémoire, et donc de l'allocation dynamique de la mémoire pour y arriver)

    Pour le même prix, tu pourrais tout aussi bien te retrouver dans une situation dans laquelle les comportements impliqués par push_back fassent tomber le système en vrille

    L'idéal est quand meme d'avoir un et un seul thread qui ait accès en écriture, à moins de faire en sorte que chaque thread qui écrit sur le vecteur n'écrive que sur une partie bien précise de celui-ci (mais sans push_back, alors)
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Par défaut
    Tu ne fais pas assez de push_back ou alors ton programme n'est pas multithreadé.

    Voici ce bout de code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    // g++ -Wall -Wextra -std=c++11 -pedantic -O3 -fopenmp push_back_thread.cpp -o push_back_thread && push_back_thread
     
    #include <iostream>
    #include <vector>
     
    int main()
    {
    	std::vector<int> v;
     
    	std::size_t const size = 10 * 1000 * 1000;
     
    	#pragma omp parallel for
    	for (std::size_t i = 0; i < size; ++i)
    	{
    		v.push_back(i);
    	}
     
    	std::cout << "Size = " << v.size() << " (size voulue = " << size << ")" << std::endl;
     
    	return 0;
    }
    Sans OpenMP (un seul thread) tout ce passe bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ g++ -Wall -Wextra -std=c++11 -pedantic -O3 push_back_thread.cpp -o push_back_thread && push_back_thread
    push_back_thread.cpp:12:0: warning: ignoring #pragma omp parallel [-Wunknown-pragmas]
    Size = 10000000 (size voulue = 10000000)
    En revanche, avec OpenMP, les erreurs varient mais ça donne carrément une SEGFAULT
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    $ g++ -Wall -Wextra -std=c++11 -pedantic -O3 -fopenmp push_back_thread.cpp -o push_back_thread && push_back_thread
    *** glibc detected *** push_back_thread: double free or corruption (!prev): 0x0000000000da5f70 ***
    ======= Backtrace: =========
    /lib/x86_64-linux-gnu/libc.so.6(+0x76d76)[0x7fc2d66b6d76]
    /lib/x86_64-linux-gnu/libc.so.6(cfree+0x6c)[0x7fc2d66bbaac]
    push_back_thread[0x400e9a]
    push_back_thread[0x400df8]
    /usr/lib/x86_64-linux-gnu/libgomp.so.1(+0x906a)[0x7fc2d6e0506a]
    /lib/x86_64-linux-gnu/libpthread.so.0(+0x6b50)[0x7fc2d69d0b50]
    /lib/x86_64-linux-gnu/libc.so.6(clone+0x6d)[0x7fc2d671aa7d]
    ======= Memory map: ========
    00400000-00402000 r-xp 00000000 08:19 20                                 /media/SSD/push_back_thread
    00601000-00602000 rw-p 00001000 08:19 20                                 /media/SSD/push_back_thread
    00da5000-00dc6000 rw-p 00000000 00:00 0                                  [heap]
    7fc2d0000000-7fc2d0021000 rw-p 00000000 00:00 0 
    7fc2d0021000-7fc2d4000000 ---p 00000000 00:00 0 
    7fc2d4c35000-7fc2d4c36000 ---p 00000000 00:00 0 
    7fc2d4c36000-7fc2d5436000 rw-p 00000000 00:00 0                          [stack:32151]
    7fc2d5436000-7fc2d5437000 ---p 00000000 00:00 0 
    7fc2d5437000-7fc2d5c37000 rw-p 00000000 00:00 0                          [stack:32150]
    7fc2d5c37000-7fc2d5c38000 ---p 00000000 00:00 0 
    7fc2d5c38000-7fc2d6438000 rw-p 00000000 00:00 0                          [stack:32149]
    7fc2d6438000-7fc2d643f000 r-xp 00000000 08:18 1579955                    /lib/x86_64-linux-gnu/librt-2.13.so
    7fc2d643f000-7fc2d663e000 ---p 00007000 08:18 1579955                    /lib/x86_64-linux-gnu/librt-2.13.so
    7fc2d663e000-7fc2d663f000 r--p 00006000 08:18 1579955                    /lib/x86_64-linux-gnu/librt-2.13.so
    7fc2d663f000-7fc2d6640000 rw-p 00007000 08:18 1579955                    /lib/x86_64-linux-gnu/librt-2.13.so
    7fc2d6640000-7fc2d67c0000 r-xp 00000000 08:18 1579962                    /lib/x86_64-linux-gnu/libc-2.13.so
    7fc2d67c0000-7fc2d69c0000 ---p 00180000 08:18 1579962                    /lib/x86_64-linux-gnu/libc-2.13.so
    7fc2d69c0000-7fc2d69c4000 r--p 00180000 08:18 1579962                    /lib/x86_64-linux-gnu/libc-2.13.so
    7fc2d69c4000-7fc2d69c5000 rw-p 00184000 08:18 1579962                    /lib/x86_64-linux-gnu/libc-2.13.so
    7fc2d69c5000-7fc2d69ca000 rw-p 00000000 00:00 0 
    7fc2d69ca000-7fc2d69e1000 r-xp 00000000 08:18 1579948                    /lib/x86_64-linux-gnu/libpthread-2.13.so
    7fc2d69e1000-7fc2d6be0000 ---p 00017000 08:18 1579948                    /lib/x86_64-linux-gnu/libpthread-2.13.so
    7fc2d6be0000-7fc2d6be1000 r--p 00016000 08:18 1579948                    /lib/x86_64-linux-gnu/libpthread-2.13.so
    7fc2d6be1000-7fc2d6be2000 rw-p 00017000 08:18 1579948                    /lib/x86_64-linux-gnu/libpthread-2.13.so
    7fc2d6be2000-7fc2d6be6000 rw-p 00000000 00:00 0 
    7fc2d6be6000-7fc2d6bfb000 r-xp 00000000 08:18 1572916                    /lib/x86_64-linux-gnu/libgcc_s.so.1
    7fc2d6bfb000-7fc2d6dfb000 ---p 00015000 08:18 1572916                    /lib/x86_64-linux-gnu/libgcc_s.so.1
    7fc2d6dfb000-7fc2d6dfc000 rw-p 00015000 08:18 1572916                    /lib/x86_64-linux-gnu/libgcc_s.so.1
    7fc2d6dfc000-7fc2d6e0a000 r-xp 00000000 08:18 655367                     /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0
    7fc2d6e0a000-7fc2d7009000 ---p 0000e000 08:18 655367                     /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0
    7fc2d7009000-7fc2d700a000 rw-p 0000d000 08:18 655367                     /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0
    7fc2d700a000-7fc2d708b000 r-xp 00000000 08:18 1579957                    /lib/x86_64-linux-gnu/libm-2.13.so
    7fc2d708b000-7fc2d728a000 ---p 00081000 08:18 1579957                    /lib/x86_64-linux-gnu/libm-2.13.so
    7fc2d728a000-7fc2d728b000 r--p 00080000 08:18 1579957                    /lib/x86_64-linux-gnu/libm-2.13.so
    7fc2d728b000-7fc2d728c000 rw-p 00081000 08:18 1579957                    /lib/x86_64-linux-gnu/libm-2.13.so
    7fc2d728c000-7fc2d7374000 r-xp 00000000 08:18 655363                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
    7fc2d7374000-7fc2d7574000 ---p 000e8000 08:18 655363                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
    7fc2d7574000-7fc2d757c000 r--p 000e8000 08:18 655363                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
    7fc2d757c000-7fc2d757e000 rw-p 000f0000 08:18 655363                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
    7fc2d757e000-7fc2d7593000 rw-p 00000000 00:00 0 
    7fc2d7593000-7fc2d75b3000 r-xp 00000000 08:18 1586319                    /lib/x86_64-linux-gnu/ld-2.13.so
    7fc2d777a000-7fc2d7781000 rw-p 00000000 00:00 0 
    7fc2d77b0000-7fc2d77b2000 rw-p 00000000 00:00 0 
    7fc2d77b2000-7fc2d77b3000 r--p 0001f000 08:18 1586319                    /lib/x86_64-linux-gnu/ld-2.13.so
    7fc2d77b3000-7fc2d77b4000 rw-p 00020000 08:18 1586319                    /lib/x86_64-linux-gnu/ld-2.13.so
    7fc2d77b4000-7fc2d77b5000 rw-p 00000000 00:00 0 
    7fffeae90000-7fffeaeb1000 rw-p 00000000 00:00 0                          [stack]
    7fffeaf88000-7fffeaf8a000 r-xp 00000000 00:00 0                          [vdso]
    ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
    Abandon
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $ g++ -Wall -Wextra -std=c++11 -pedantic -O3 -fopenmp push_back_thread.cpp -o push_back_thread && push_back_thread
    *** glibc detected *** push_back_thread: free(): invalid next size (fast): 0x000000000250bc20 ***
    ======= Backtrace: =========
    /lib/x86_64-linux-gnu/libc.so.6(+0x76d76)[0x7ff5ef076d76]
    /lib/x86_64-linux-gnu/libc.so.6(cfree+0x6c)[0x7ff5ef07baac]
    push_back_thread[0x400e9a]
    push_back_thread[0x400df8]
    push_back_thread[0x400bb0]
    Erreur de segmentation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ g++ -Wall -Wextra -std=c++11 -pedantic -O3 -fopenmp push_back_thread.cpp -o push_back_thread && push_back_thread
    *** glibc detected *** push_back_threadErreur de segmentation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ g++ -Wall -Wextra -std=c++11 -pedantic -O3 -fopenmp push_back_thread.cpp -o push_back_thread && push_back_thread
    *** glibc detected *** Erreur de segmentation

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Bonsoir,
    Citation Envoyé par piet1 Voir le message
    Ce que je trouve anormal c'est que j'ai utilisé 10 threads qui accède au même vecteur pour ajouter des case de données avec puch_back sans mutex pour l'instant y'a aucun problème.
    C'est ce qu'on apelle tomber en marche.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. accés concurrent à une table
    Par shout dans le forum Oracle
    Réponses: 5
    Dernier message: 06/10/2005, 10h54
  2. Réponses: 22
    Dernier message: 25/08/2005, 16h03
  3. Lenteur et acces concurrent
    Par JeanMarc_T2k dans le forum Bases de données
    Réponses: 7
    Dernier message: 04/12/2004, 20h57
  4. acces concurrent avec delphi 5 entreprise
    Par Jean_paul dans le forum Bases de données
    Réponses: 2
    Dernier message: 30/11/2004, 20h19
  5. [EJB] Accès concurrents à la base de données
    Par cameleon2002 dans le forum Java EE
    Réponses: 10
    Dernier message: 23/09/2003, 11h31

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