pthread_exit引发的异常

superhackerzhang 2011-11-11 06:15:27
首先说明一下程序情况
在主函数中创建两个线程,调用caller

pthread_create(&s,NULL,caller,&in1);
pthread_create(&t,NULL,caller,&in2);
pthread_join(s,&hm1);
pthread_join(t,&hm2);


caller调用类中的静态方法bfs

void *caller(void * arg)
{
long long it=sixdegreeI::bfs(arg);
return (void*)it;
}


bfs中实现广度搜索

long long sixdegreeI::bfs(void * arg)
{
signal(SIGTERM,handler);
//此处省略many行
int pkillre=pthread_kill(kill,0);
if(pkillre!=ESRCH&&pkillre!=EINVAL)
{
pthread_kill(kill,SIGTERM);//kill为两个线程中另一个线和的TID

}
}

在线程中用handler来处理SIGTERM信号,目是使用一个线程通知另一个线程退出

void handler(int a)
{
pthread_exit(0);
//return ;
}


但运行若干次就会有一次出现异常,如下:

terminate called without an active exception

Program received signal SIGABRT, Aborted.
0x0000003ca772e26d in raise () from /lib64/tls/libc.so.6
(gdb) bt
#0 0x0000003ca772e26d in raise () from /lib64/tls/libc.so.6
#1 0x0000003ca772fa6e in abort () from /lib64/tls/libc.so.6
#2 0x0000003ca9bb11be in __gnu_cxx::__verbose_terminate_handler () from /usr/lib64/libstdc++.so.6
#3 0x0000003ca9baf176 in __cxa_call_unexpected () from /usr/lib64/libstdc++.so.6
#4 0x0000003ca9baf1a3 in std::terminate () from /usr/lib64/libstdc++.so.6
#5 0x0000003ca9baf03a in __gxx_personality_v0 () from /usr/lib64/libstdc++.so.6
#6 0x0000003ca8a089e5 in _Unwind_RaiseException () from /lib64/libgcc_s.so.1
#7 0x0000003ca8a08afc in _Unwind_ForcedUnwind () from /lib64/libgcc_s.so.1
#8 0x0000003ca800add0 in __pthread_unwind () from /lib64/tls/libpthread.so.0
#9 0x0000003ca8006fb5 in pthread_exit () from /lib64/tls/libpthread.so.0
#10 0x000000000040bf7d in handler (a=15) at server.cpp:24
#11 <signal handler called>
#12 0x0000003ca776b6e6 in malloc () from /lib64/tls/libc.so.6
#13 0x0000003ca9baf5aa in operator new () from /usr/lib64/libstdc++.so.6
#14 0x000000000041412a in __gnu_cxx::new_allocator<__gnu_cxx::_Hashtable_node<std::pair<long long const, char> > >::allocate
(this=0x42803060, __n=1) at /usr/lib/gcc/x86_64-redhat-linux/3.4.6/../../../../include/c++/3.4.6/ext/new_allocator.h:81
#15 0x000000000041287b in __gnu_cxx::hashtable<std::pair<long long const, char>, long long, longtoint, std::_Select1st<std::pair<long long const, char> >, std::equal_to<long long>, std::allocator<char> >::_M_get_node (this=0x42803060)
at /usr/lib/gcc/x86_64-redhat-linux/3.4.6/../../../../include/c++/3.4.6/ext/hashtable.h:252
#16 0x0000000000410e9a in __gnu_cxx::hashtable<std::pair<long long const, char>, long long, longtoint, std::_Select1st<std::pair<long long const, char> >, std::equal_to<long long>, std::allocator<char> >::_M_new_node (this=0x42803060,
__obj=@0x42802e90) at /usr/lib/gcc/x86_64-redhat-linux/3.4.6/../../../../include/c++/3.4.6/ext/hashtable.h:528
#17 0x000000000040f34d in __gnu_cxx::hashtable<std::pair<long long const, char>, long long, longtoint, std::_Select1st<std::pair<long long const, char> >, std::equal_to<long long>, std::allocator<char> >::find_or_insert (this=0x42803060,
__obj=@0x42802e90) at /usr/lib/gcc/x86_64-redhat-linux/3.4.6/../../../../include/c++/3.4.6/ext/hashtable.h:710
#18 0x000000000040e5c6 in __gnu_cxx::hash_map<long long, char, longtoint, std::equal_to<long long>, std::allocator<char> >::operator[] (this=0x42803060, __key=@0x1e2c850)
at /usr/lib/gcc/x86_64-redhat-linux/3.4.6/../../../../include/c++/3.4.6/ext/hash_map:181
#19 0x000000000040c6f9 in sixdegreeI::bfs (arg=0x413fff20) at server.cpp:124
#20 0x000000000040bfc3 in caller (arg=0x413fff20) at server.cpp:30
#21 0x0000003ca8006137 in start_thread () from /lib64/tls/libpthread.so.0
#22 0x0000003ca77c9883 in clone () from /lib64/tls/libc.so.6
(gdb)


很明显是由pthread_exit引起的异常,但在man中并没有说明pthread_exit()会有异常,在把pthread_exit()改为return后异常便消失了。

但我有个疑问,用return而非pthread_exit()会不会有问题,比如内存泄露。
...全文
1201 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
superhackerzhang 2011-11-13
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 qq120848369 的回复:]

引用 3 楼 superhackerzhang 的回复:

引用 1 楼 qq120848369 的回复:

NOTES

SIGTERM信号不能单独发给一个线程,将会直接影响整个进程,影响结果估计是主线程的signal行为,直接退了,或者说pthread_kill SIGTERM是个未定义行为。


你这句我不认同,SIGTERM可以发送给一个线程,为了不影响整个进程,在线程……
[/Quote]

大哥别激动,你说的有道理,是我的理解有问题。
qq120848369 2011-11-13
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 superhackerzhang 的回复:]

引用 1 楼 qq120848369 的回复:

NOTES

SIGTERM信号不能单独发给一个线程,将会直接影响整个进程,影响结果估计是主线程的signal行为,直接退了,或者说pthread_kill SIGTERM是个未定义行为。


你这句我不认同,SIGTERM可以发送给一个线程,为了不影响整个进程,在线程中要接受信号,并对信号作出处理,这样就不会影响其它线程与父进程了……
[/Quote]

你就没看懂我说什么。

请问,一个信号函数的返回值是什么?

void sighandler(int signo);

你返回什么? pthread_exit(0) ? 你以为信号处理函数就和线程里调用个普通函数一样么?
qq120848369 2011-11-12
  • 打赏
  • 举报
回复
void handler(int a)
{
pthread_exit(0);
//return ;
}

这个函数不是线程,你干嘛要pthread_exit。。返回值是void啊,我可真没见过这样做的,虽然说信号处理函数会中断信号接收线程,但这不意味着它们是调用和被调用关系。 return正常就很容易理解了。

qq120848369 2011-11-12
  • 打赏
  • 举报
回复
NOTES
Signal dispositions are process-wide: if a signal handler is installed, the handler will be invoked in the thread thread, but if the disposition
of the signal is "stop", "continue", or "terminate", this action will affect the whole process.

SIGTERM信号不能单独发给一个线程,将会直接影响整个进程,影响结果估计是主线程的signal行为,直接退了,或者说pthread_kill SIGTERM是个未定义行为。


APPLICATION USAGE
The pthread_kill() function provides a mechanism for asynchronously directing a signal at a thread in the calling process. This could be used, for
example, by one thread to affect broadcast delivery of a signal to a set of threads.

Note that pthread_kill() only causes the signal to be handled in the context of the given thread; the signal action (termination or stopping)
affects the process as a whole.


这都是类似的说明。
superhackerzhang 2011-11-12
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 qq120848369 的回复:]

NOTES

SIGTERM信号不能单独发给一个线程,将会直接影响整个进程,影响结果估计是主线程的signal行为,直接退了,或者说pthread_kill SIGTERM是个未定义行为。
[/Quote]

你这句我不认同,SIGTERM可以发送给一个线程,为了不影响整个进程,在线程中要接受信号,并对信号作出处理,这样就不会影响其它线程与父进程了。就如我在所做的,在线程中使用signal来接收,并调用handler来
处理SIGTERM

23,223

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧