c++ - std::thread 创建抛出异常

标签 c++ linux multithreading g++ c++11

代码:

#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

结果:

creating thread
Operation not permitted

如何解决这个问题?

编辑:
使用 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)                           = ?

最佳答案

您的问题是您忘记为编译器指定 -lpthread-pthread 标志。因此,它在构建程序时采用单线程模式。

标准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

我不想为此检查源代码,但很可能他们使用“惰性”动态链接来确定 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)
$ 

希望对您有所帮助。祝你好运!

关于c++ - std::thread 创建抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9945391/

相关文章:

c++ - 我可以使用 tie 将一对元素放入 vector 中吗?

c++ - optarg 设置为空

c++ - 以下问题的蛮力技术

linux - 使用 cut 显示来自上一个命令 linux 的信息

C# 同步对象 - 具有写入访问器的重复代码

c++ - 如何用pthread获取信号量的信息

c++ - glOrtho 不工作

java - 使用 shell 命令运行项目

php - mysql无法创建外键错误121但不存在

java - 我的应用程序卡住,如何在其中实现线程?