std ::线程创建抛出异常 [英] std::thread creation throws exception

查看:614
本文介绍了std ::线程创建抛出异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

代码:

  #include< iostream> 
#include< thread>

void hello()
{
std :: cout<< Hello World<<的std :: ENDL;
}

int main()
{
try
{
std :: cout<< 创建线程<<的std :: ENDL;
std :: thread t(hello);
std :: cout<< 等待<<的std :: ENDL;
t.join();
std :: cout<< 完成<<的std :: ENDL;
}
catch(std :: exception& ex)
{
std :: cout<< ex.what()<<的std :: ENDL;




$ b $建立:



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
输出大小为106.62 KB
过程以状态0终止(0分钟,0秒)
0错误,0警告

结果:


创建线程

不允许的操作


这可以如何解决?

编辑:

运行程序with strace:


$ b

alex @ alex-64:〜/ tmp / thread_test / bin / Debug $ strace ./thread_test
execve(./ thread_test,[./thread_test],[/ * 38 vars * /])= 0
brk(0)= 0x189a000
(/etc/ld.so.nohwcap,F_OK)= -1 ENO ENT(没有这样的文件或目录)
mmap(NULL,8192,PROT_READ | PROT_WRITE,MAP_PRIVATE | MAP_ANONYMOUS,-1,0)= 0x7f7c60cbc000
access(/ etc / ld.so.preload, (/ 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 / (没有这样的文件或目录)
open(/ usr / lib / x86_64-linux-gnu / libstdc ++。so.6,O_RDONLY)= 3
read(3,\177ELF\2\1\1\0\0\\\\\\\\\\\ \\ 0 \\> 0 \ 1 \ 0 \\\\\\\\\\\\\\\\\',8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 b $ b 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
mprotec t(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(没有这样的文件或目录)
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 (3,{st_mode = S_IFREG | 0644,st_size = 88384,...,832)= 832
fstat(3,{st_mode = S_IFREG | ...})= 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(无此文件或目录)
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\\\\\\\\\\\\\\\\\\' 2,...,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(0x7f7c605776000,201180,PROT_READ | PROT_WRITE,MAP_PRIVATE | MAP_FIXED | MAP_DENYWRITE,3,0x196000)= 0x7f7c60576000
mmap(0x7f7c6057b000,213352, PROT_READ | PROT_WRITE,MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS,-1,0)= 0x7f 7c6057b000
close(3)= 0
access(/ etc / ld.so.nohwcap,F_OK)= -1 ENOENT(没有这样的文件或目录)
open(/ lib /x86_64-linux-gnu/libm.so.6,O_RDONLY)= 3
read(3,\177ELF\2\1\\\\\\\\\\' 0\0\0\0\0\0\3\0> \0\1\0\0\0\360> \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)= 0x7f (0x7f7c601de000,4096,PROT_READ)= 0
mprotect(0x7f7c60576000,16384,PROT_READ)= 0
mprotect(0x7f7c60795000,4096)
arch_prctl(ARCH_SET_FS,0x7f7c60c9a740)= 0
mprotect ,PROT_READ)= 0
mmap(NULL,4096,PROT_READ | PROT_WRITE,MAP_PRIVATE | MAP_ANONYMOUS,-1,0)= 0x7f7c60c99000
mprotect(0x7f7c60a7f000,32768,PROT_READ)= 0
mprotect (1,{st_mode = S_IFCHR | 0620,st_rdev,0x603000,4096,PROT_READ)= 0
mprotect(0x7f7c60cbe000,4096,PROT_READ)= 0
munmap(0x7f7c60c9e000,121299)= 0
mmap(NULL,4096,PROT_READ | PROT_WRITE,MAP_PRIVATE | MAP_ANONYMOUS,-1,0)= 0x7f7c60cbb000
write(1,create, (1,不允许的操作,\),16创建线程
)= 16
brk(0)= 0x189a000
brk(0x18bb000)= 0x18bb000
write ,24不允许操作
)= 24
exit_group(0)= ?


解决方案

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



标准C ++库抛出异常:

 (gdb)catch throw 
函数__cxa_throw未定义。
Catchpoint 1(throw)
(gdb)run
启动程序:/ tmp / test
创建线程
__cxa_throw()中的Catchpoint 1(抛出异常),0x00007ffff7b8eff0从/ usr / lib / x86_64-linux-gnu / libstdc ++的/usr/lib/x86_64-linux-gnu/libstdc++.so.6
(gdb)其中
#0 0x00007ffff7b8eff0位于__cxa_throw()中。 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: :在/usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3中的_M_start_thread(std :: shared_ptr (gdb)退出

我不想检查源代码,但很可能它们使用懒惰动态链接以确定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)
$

希望它有帮助。祝你好运!


Code:

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

Build:

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

Result:

creating thread
Operation not permitted

How this can be fixed?

Edit:
Running the program with 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)                           = ?

解决方案

Your problem is that you forgot to specify -lpthread or -pthread flag to the compiler. So it assumes a single-threaded mode when building your program.

The exception is thrown by the standard C++ library:

(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

I don't have any desire to check source code for that, but it is most likely they use "lazy" dynamic linking to determine if POSIX threads family of functions are available. And throw exceptions otherwise. That way, you get that exception unless linking with pthread library.

That has nothing to do with virtual memory or other resource limits as I initially thought might be happening because system calls do not report any errors. So just do:

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

... and it will work.

UPDATE:

As @ildjaRN pointed out, you already specify -pthread. I suggest you specify it after your object files (source files for a single invocation compile & link), otherwise it might not get picked up.

Here is how to make sure it is picked up - you can run ldd and make sure that pthread.so makes it 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)
$ 

Hope it helps. Good luck!

这篇关于std ::线程创建抛出异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆