2012-03-30 5 views
7

Code:std :: Thread-Erzeugung wirft Ausnahme

#include <iostream> 
#include <thread> 

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; 
    } 
} 

Körperbau:

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 

Ergebnis:

Schaffung Thread
Betrieb nicht

0 zulässig

Wie kann das behoben werden?

Edit:
das Programm mit strace Lauf:

[email protected]:~/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)       = ? 
+0

Welche Version von gcc? – mark

+0

g ++ (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1 –

+1

tun "strace" und sehen, welche Systemaufrufe Sie mit "nicht erlaubt" ablehnen. Es hat wenig mit deinem Code zu tun, mehr mit Berechtigungen, Prozessattributen usw. (wie ulimit) –

Antwort

11

Ihr Problem ist, dass Sie -lpthread oder -pthread Flag an den Compiler zu spezifizieren vergessen. Daher wird beim Erstellen Ihres Programms ein Singlethread-Modus vorausgesetzt.

Die Ausnahme wird von der Standard-C++ Bibliothek geworfen:

(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<std::thread::_Impl_base>)() from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 
#3 0x00000000004012d4 in std::thread::thread<void (&)()>(void (&&&)())() 
#4 0x0000000000400f0e in main() 
(gdb) quit 

Ich habe keine Lust haben, den Quellcode für das zu überprüfen, aber es ist sehr wahrscheinlich, dass sie „faul“ dynamische Verknüpfung verwenden, um festzustellen, ob Die POSIX-Thread-Funktionsfamilie ist verfügbar. Und Ausnahmen sonst werfen. Auf diese Weise erhalten Sie diese Ausnahme, wenn Sie nicht mit der pthread-Bibliothek verknüpfen.

Das hat nichts mit virtuellem Speicher oder anderen Ressourcenlimits zu tun, wie ich anfangs dachte, weil Systemaufrufe keine Fehler melden. Also einfach:

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

... und es wird funktionieren.

UPDATE:

Wie @ildjaRN wies darauf hin, geben Sie bereits -pthread. Ich schlage vor, dass Sie es nach Ihren Objektdateien angeben (Quelldateien für einen einzelnen Aufruf kompilieren & Link), sonst wird es möglicherweise nicht abgeholt.

Hier ist, wie um sicherzustellen, dass es aufgenommen wird - Sie ldd und stellen Sie sicher ausgeführt werden kann, dass pthread.so macht es in:

$ 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) 
$ 

Hoffe, es hilft. Viel Glück!

+0

Seine g ++ -Aufrufung speziell _does_ hat '-pthread'. – ildjarn

+2

@ildjarn: Im Allgemeinen müssen Bibliotheken NACH Objektdateien spezifiziert werden oder sie werden nicht eingezogen. Es gab einen Fehler mit Linker in einigen Versionen von gcc (4.6.1 glaube ich), wo dies nicht der Fall war, und wurde später behoben . –

+0

Es sieht aus wie das Problem wirklich in -thread-Schalter ist. Es bis zum Ende zu bewegen, hat nicht geholfen. Ausführen von LDD./ thread_test | grep pthread erzeugt keine Ausgabe. –