2012-03-30 49 views
7

Code:tạo std :: chủ đề ném ngoại lệ

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

tích xây dựng:

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 

Kết quả:

tạo chủ đề
Operation không được phép

Làm cách nào để khắc phục sự cố này?

Edit:
Chạy chương trình với 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

phiên bản gcc nào? – mark

+0

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

+1

thực hiện "strace" và xem những lời gọi hệ thống từ chối bạn với "không được phép". Nó có rất ít để làm với mã của bạn, nhiều hơn với quyền hạn, quá trình thuộc tính, vv (như ulimit) –

Trả lời

11

Vấn đề của bạn là bạn quên để xác định -lpthread hoặc -pthread cờ để trình biên dịch. Vì vậy, nó giả định một chế độ đơn luồng khi xây dựng chương trình của bạn.

Trường hợp ngoại lệ được ném theo tiêu chuẩn C++ thư viện:

(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 

tôi không có bất kỳ mong muốn kiểm tra mã nguồn cho điều đó, nhưng nó rất có thể là họ sử dụng "lười biếng" liên kết động để xác định xem Chủ đề của POSIX là các chức năng có sẵn. Và ném ngoại lệ khác. Bằng cách đó, bạn nhận được ngoại lệ đó trừ khi liên kết với thư viện pthread.

Điều đó không liên quan gì đến bộ nhớ ảo hoặc các giới hạn tài nguyên khác như tôi nghĩ ban đầu có thể xảy ra vì cuộc gọi hệ thống không báo cáo bất kỳ lỗi nào. Vì vậy, chỉ cần làm:

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

... và nó sẽ làm việc.

CẬP NHẬT:

Như @ildjaRN đã chỉ ra, bạn đã chỉ định -pthread. Tôi đề nghị bạn chỉ định nó sau khi các tệp đối tượng của bạn (tệp nguồn cho một biên dịch gọi đơn lẻ biên dịch &), nếu không nó có thể không được chọn.

Dưới đây là làm thế nào để chắc chắn rằng nó được nhặt - bạn có thể chạy ldd và chắc chắn rằng pthread.so làm cho nó trong:

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

Hy vọng nó giúp. Chúc may mắn!

+0

Yêu cầu g ++ của anh cụ thể _does_ có '-pthread'. – ildjarn

+2

@ildjarn: Thông thường bạn phải chỉ định thư viện SAU KHI các tệp đối tượng hoặc chúng không được kéo vào. Có lỗi với trình liên kết trong một số phiên bản của gcc (4.6.1 tôi tin). . –

+0

Dường như vấn đề thực sự là trong chuyển đổi -pthread. Di chuyển nó đến cùng không giúp được gì. Thực hiện ldd./ thread_test | grep pthread không tạo ra bất kỳ đầu ra nào. –

Các vấn đề liên quan