2012-03-30 23 views
7

कोड:std :: धागा निर्माण फेंकता अपवाद

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

बिल्ड:

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 

परिणाम:

बनाने धागा
कार्रवाई की अनुमति नहीं

यह कैसे तय किया जा सकता है?

संपादित करें:
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

जीसीसी का कौन सा संस्करण? – mark

+0

जी ++ (उबंटू/लिनारो 4.6.1-9ubuntu3) 4.6.1 –

+1

"स्ट्रेस" करें और देखें कि कौन सी सिस्टम कॉल आपको "अनुमति नहीं है" के साथ अस्वीकार करती है। यह आपके कोड के साथ बहुत कम है, अनुमतियों के साथ, प्रक्रिया विशेषताओं, आदि (जैसे ulimit) –

उत्तर

11

आपकी समस्या यह है कि आप संकलक को -lpthread या -pthread ध्वज निर्दिष्ट करना भूल गए है। इसलिए यह आपके प्रोग्राम का निर्माण करते समय एकल-थ्रेडेड मोड मानता है।

अपवाद मानक सी ++ पुस्तकालय द्वारा फेंका जाता है:

(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 

मुझे लगता है कि के लिए स्रोत कोड की जांच के लिए किसी भी इच्छा नहीं है, लेकिन यह वे अगर निर्धारित करने के लिए "सुस्त" गतिशील जोड़ने का उपयोग सबसे अधिक संभावना है कार्यों के POSIX धागे परिवार उपलब्ध हैं। और अन्यथा अपवाद फेंक दें। इस तरह, आप उस अपवाद को तब तक प्राप्त करते हैं जब तक कि pthread लाइब्रेरी से लिंक न हो।

वर्चुअल मेमोरी या अन्य संसाधन सीमाओं के साथ इसका कोई लेना-देना नहीं है क्योंकि मैंने शुरू में सोचा था क्योंकि सिस्टम कॉल किसी भी त्रुटि की रिपोर्ट नहीं करता है। तो बस करें:

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

... और यह काम करेगा।

अद्यतन:

@ildjaRN के रूप में बताया, तो आप पहले से ही -pthread निर्दिष्ट करें। मेरा सुझाव है कि आप इसे अपनी ऑब्जेक्ट फ़ाइलों के बाद निर्दिष्ट करें (एक एकल आमंत्रण संकलन के लिए स्रोत फ़ाइलें & लिंक), अन्यथा यह उठाया नहीं जा सकता है।

यहाँ कैसे यकीन है कि यह उठाया जाता है बनाने के लिए है - आप ldd चलाने के लिए और सुनिश्चित करें कि pthread.so में यह बनाता है बना सकते हैं:

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

आशा है कि यह मदद करता है। सौभाग्य!

+0

उनके जी ++ आमंत्रण विशेष रूप से _does_ में '-pthread' है। – ildjarn

+2

@ildjarn: आपको आमतौर पर ऑब्जेक्ट फ़ाइलों के बाद पुस्तकालयों को निर्दिष्ट करना होता है या उन्हें खींच नहीं लिया जाता है। जीसीसी के कुछ संस्करणों में लिंकर के साथ एक बग था (4.6.1 मुझे विश्वास है) जहां यह मामला नहीं था, और बाद में तय हो गया । –

+0

ऐसा लगता है कि समस्या वास्तव में -थ्रेड स्विच में है। इसे अंत तक ले जाने से मदद नहीं मिली। निष्पादन निष्पादित/ thread_test | grep pthread किसी भी आउटपुट का उत्पादन नहीं करता है। –

संबंधित मुद्दे