2012-03-30 13 views
7

Codice:creazione std :: filo getta eccezione

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

Corporatura:

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 

Risultato:

creando filo
Operazione non consentita

Come può essere risolto?

Edit:
Esecuzione del programma con strace:

[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

quale versione di gcc? – mark

+0

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

+1

fare "strace" e vedere quali chiamate di sistema ti rifiutano con "non consentito". Ha poco a che fare con il tuo codice, più con permessi, attributi di processo, ecc. (Come ulimit) –

risposta

11

Il tuo problema è che si è dimenticato di specificare -lpthread o -pthread flag per il compilatore. Quindi assume una modalità a thread singolo durante la creazione del programma.

L'eccezione viene generata dalla libreria standard C++:

(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 

Non ho alcun desiderio di controllare il codice sorgente per questo, ma è più probabile che usano "pigro" linking dinamico per determinare se Sono disponibili le famiglie di funzioni dei thread POSIX. E gettare eccezioni altrimenti. In questo modo, ottieni questa eccezione a meno che non si colleghi alla libreria pthread.

Questo non ha nulla a che fare con la memoria virtuale o altri limiti di risorse come inizialmente pensavo potesse accadere perché le chiamate di sistema non riportano errori. Quindi basta:

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

... e funzionerà.

UPDATE:

Come @ildjaRN ha sottolineato, è già specificato -pthread. Suggerisco di specificarlo dopo i file oggetto (file di origine per un singolo collegamento di compilazione &), altrimenti potrebbe non essere rilevato.

Ecco come assicurarsi che viene raccolto - è possibile eseguire ldd e assicurarsi che pthread.so rende 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) 
$ 

Speranza che aiuta. In bocca al lupo!

+0

La sua chiamata g ++ in particolare _does_ ha '-pthread'. – ildjarn

+2

@ildjarn: Generalmente devi specificare le librerie DOPO i file oggetto o non vengono estratti. C'era un bug con il linker in alcune versioni di gcc (4.6.1 credo) dove non era questo il caso, e in seguito è stato corretto . –

+0

Sembra che il problema sia davvero un cambiamento in -pthread. Spostarlo fino alla fine non ha aiutato. Esecuzione ldd./ thread_test | grep pthread non produce alcun output. –

Problemi correlati