std :: la création de threads génère une exception

Code:

#include  #include  void hello() { std::cout << "Hello World" << std::endl; } int main() { try { std::cout << "creating thread" << std::endl; std::thread t(hello); std::cout << "waiting" << std::endl; t.join(); std::cout << "done" << std::endl; } catch(std::exception& ex) { std::cout << ex.what() << std::endl; } } 

Construire:

 g++ -Wall -fexceptions -std=c++0x -pthread -g -c /home/alex/tmp/thread_test/main.cpp -o obj/Debug/main.o g++ -o bin/Debug/thread_test obj/Debug/main.o Output size is 106.62 KB Process terminated with status 0 (0 minutes, 0 seconds) 0 errors, 0 warnings 

Résultat:

créer un fil
Opération non autorisée

Comment cela peut être corrigé?

Modifier:
Lancer le programme avec strace:

 alex@alex-64:~/tmp/thread_test/bin/Debug$ strace ./thread_test execve("./thread_test", ["./thread_test"], [/* 38 vars */]) = 0 brk(0) = 0x189a000 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7c60cbc000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=121299, ...}) = 0 mmap(NULL, 121299, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7c60c9e000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/usr/lib/x86_64-linux-gnu/libstdc++.so.6", O_RDONLY) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\244\5\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0644, st_size=991424, ...}) = 0 mmap(NULL, 3171440, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7c60797000 mprotect(0x7f7c6087f000, 2097152, PROT_NONE) = 0 mmap(0x7f7c60a7f000, 40960, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xe8000) = 0x7f7c60a7f000 mmap(0x7f7c60a89000, 83056, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f7c60a89000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/libgcc_s.so.1", O_RDONLY) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260(\0\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0644, st_size=88384, ...}) = 0 mmap(NULL, 2184216, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7c60581000 mprotect(0x7f7c60596000, 2093056, PROT_NONE) = 0 mmap(0x7f7c60795000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x14000) = 0x7f7c60795000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \24\2\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=1685816, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7c60c9d000 mmap(NULL, 3801960, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7c601e0000 mprotect(0x7f7c60377000, 2093056, PROT_NONE) = 0 mmap(0x7f7c60576000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x196000) = 0x7f7c60576000 mmap(0x7f7c6057b000, 21352, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f7c6057b000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360>\0\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0644, st_size=538928, ...}) = 0 mmap(NULL, 2633960, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7c5ff5c000 mprotect(0x7f7c5ffdf000, 2093056, PROT_NONE) = 0 mmap(0x7f7c601de000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x82000) = 0x7f7c601de000 close(3) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7c60c9c000 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7c60c9a000 arch_prctl(ARCH_SET_FS, 0x7f7c60c9a740) = 0 mprotect(0x7f7c601de000, 4096, PROT_READ) = 0 mprotect(0x7f7c60576000, 16384, PROT_READ) = 0 mprotect(0x7f7c60795000, 4096, PROT_READ) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7c60c99000 mprotect(0x7f7c60a7f000, 32768, PROT_READ) = 0 mprotect(0x603000, 4096, PROT_READ) = 0 mprotect(0x7f7c60cbe000, 4096, PROT_READ) = 0 munmap(0x7f7c60c9e000, 121299) = 0 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7c60cbb000 write(1, "creating thread\n", 16creating thread ) = 16 brk(0) = 0x189a000 brk(0x18bb000) = 0x18bb000 write(1, "Operation not permitted\n", 24Operation not permitted ) = 24 exit_group(0) = ? 

Votre problème est que vous avez oublié de spécifier l’ -lpthread ou -pthread au compilateur. Il prend donc un mode mono-thread lors de la création de votre programme.

L’exception est levée par la bibliothèque C ++ standard:

 (gdb) catch throw Function "__cxa_throw" not defined. Catchpoint 1 (throw) (gdb) run Starting program: /tmp/test creating thread Catchpoint 1 (exception thrown), 0x00007ffff7b8eff0 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (gdb) where #0 0x00007ffff7b8eff0 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #1 0x00007ffff7b3ba3e in std::__throw_system_error(int) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #2 0x00007ffff7b45cb7 in std::thread::_M_start_thread(std::shared_ptr) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #3 0x00000000004012d4 in std::thread::thread(void (&&&)()) () #4 0x0000000000400f0e in main () (gdb) quit 

Je n’ai aucun désir de vérifier le code source pour cela, mais il est fort probable qu’ils utilisent un lien dynamic “paresseux” pour déterminer si les familles de fonctions des threads POSIX sont disponibles. Et jetez des exceptions autrement. De cette façon, vous obtenez cette exception à moins de lier avec la bibliothèque pthread.

Cela n’a rien à voir avec la mémoire virtuelle ou d’autres limites de ressources, comme je le pensais au départ, car les appels système ne signalent aucune erreur. Alors faites simplement:

 g++ -std=c++0x -o test ./test.cpp -pthread 

… et ça va marcher.

METTRE À JOUR:

Comme @ildjaRN l’a souligné, vous spécifiez déjà -pthread. Je vous suggère de le spécifier après vos fichiers objects (fichiers source pour une compilation et un lien d’appel unique), sinon il risque de ne pas être capté.

Voici comment vous assurer qu’il est capté – vous pouvez lancer ldd et vous assurer que pthread.so le fait:

 $ g++ -std=c++0x -lpthread -o test ./test.cpp $ ldd ./test | grep pthread $ g++ -std=c++0x -o test ./test.cpp -lpthread $ ldd ./test | grep pthread libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff2a9073000) $ 

J’espère que cela aide. Bonne chance!