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
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
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
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.
Salut,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
Tu ne fais pas assez de push_back ou alors ton programme n'est pas multithreadé.
Voici ce bout de code :
Sans OpenMP (un seul thread) tout ce passe bien :
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; }
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 $ 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)
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
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.
Partager