免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 9841 | 回复: 4
打印 上一主题 下一主题

有关pthread_join()的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-11-24 23:37 |只看该作者 |倒序浏览
请问一下,如果pthread_join()函数等待的那个线程异常终止了或者说突然core掉了,那么pthread_join()能够返回吗?

有没有一种方法能够检查一个线程的状态,当这个线程终止时(不管哪种形式的终止,正常/异常),能够重新把这个线程拉起来?

现在我想的方法是再另外起一个监视线程B调用pthread_join()函数等待被监视线程A,如果被监视线程A突然挂掉了,那么pthread_join()函数会返回,这时,监视线程B重新调用pthread_create()重新创建一个线程C,这个线程C调用与被监视线程A相同的线程处理函数,来达到继续处理线程A需要处理的任务的目的。

写了一段测试代码,当线程A正常终止时,上面的方法是可行的;现在的问题就是,如果线程A core dump,那上面那个方法还能生效吗?

P.S. 线程A的处理函数会有一个很长的处理逻辑或者无限循环处理某些任务。

测试代码如下:

  1. #include <stdio.h>
  2. #include <pthread.h>

  3. static pthread_t tid[2];

  4. void test1()
  5. {
  6.         printf("thread1 continue, tid[%d]\n", pthread_self());
  7.         sleep(5);
  8. }

  9. void test2()
  10. {
  11.         while(1) {
  12.                 pthread_join(tid[0], NULL);
  13.                 printf("thread2 continue, tid[%d]\n", pthread_self());

  14.                 pthread_create(&tid[0], NULL, (void *(*)(void *))test1, NULL);

  15.         }
  16. }

  17. int main()
  18. {
  19.         int ret;

  20.         pthread_create(&tid[0], NULL, (void *(*)(void *))test1, NULL);
  21.         pthread_create(&tid[1], NULL, (void *(*)(void *))test2, NULL);

  22.         pthread_join(tid[1], NULL);
  23.         return 0;
  24. }

复制代码

论坛徽章:
0
2 [报告]
发表于 2007-11-25 10:28 |只看该作者

回复 #1 ratc 的帖子

解决了,上面的方法可以解决被监视线程终止的情况,但是不能解决线程被意外挂起的情况。

利用自定义信号和alarm就可解决挂起问题
解决方法是装载两个信号处理函数并设定alarm,一个处理alarm超时时,利用上面的方法重新启动一个线程C处理线程A的任务,并重新设定alarm;一个处理自定义信号,比如SIGUSR1,方法是在被监视线程A的处理函数中利用raise()函数定期发送SIGUSR1信号,该信号处理函数当捕捉到这个信号时就重设alarm值,这样新的值会代替久的值,那么时钟就不会超时,如果一段时间后没有收到这个信号,则被监视线程A就可能被挂起了,于是会执行处理alarm超时的处理函数。
到此,两个方法同时使用就可监视线程A,当A意外终止或被挂起的时候可以将它拉起。

P.S. 这里的监视线程A的处理函数要循环处理某些任务,被认为是将会一直运行的线程,所以任何情况的终止和挂起都是不被允许的。

测试代码如下:

  1. #include <stdio.h>
  2. #include <pthread.h>
  3. #include <signal.h>
  4. #include <time.h>

  5. #define CHECK_THREAD_TIME 60

  6. static pthread_t tid[2];

  7. static void test1()
  8. {
  9.         while(1) {
  10.                 printf("thread1 continue, tid[%d]\n", pthread_self());
  11.                 raise(SIGUSR1);
  12.                 sleep(5);
  13.         }
  14. }

  15. static void test2()
  16. {
  17.         while(1) {
  18.                 pthread_join(tid[0], NULL);
  19.                 printf("thread2 continue, tid[%d]\n", pthread_self());

  20.                 pthread_create(&tid[0], NULL, (void *(*)(void *))test1, NULL);

  21.         }
  22. }

  23. static void
  24. overtime_handler(int signo)
  25. {
  26.         time_t tm;

  27.         //time alarm
  28.         printf("abnormal: thread has been hanged, time[%s], restart...\n", ctime(&tm));

  29.         pthread_create(&tid[0], NULL, (void *(*)(void *))test1, NULL);
  30.         alarm(CHECK_THREAD_TIME);
  31. }

  32. static void
  33. resetalarm_handler(int signo)
  34. {
  35.         int ret;

  36.         ret = alarm(CHECK_THREAD_TIME);
  37.         printf("oh yeah! thread is still running, after [%d] seconds alarm will overtime\n", ret);
  38. }

  39. int main()
  40. {
  41.         int ret;

  42.         struct sigaction sa;
  43.         memset(&sa, 0x0, sizeof(sa));
  44.         sa.sa_handler = overtime_handler;
  45.         sigaction(SIGALRM, &sa, NULL);

  46.         sa.sa_handler = resetalarm_handler;
  47.         sigaction(SIGUSR1, &sa, NULL);

  48.         alarm(CHECK_THREAD_TIME);

  49.         pthread_create(&tid[0], NULL, (void *(*)(void *))test1, NULL);
  50.         pthread_create(&tid[1], NULL, (void *(*)(void *))test2, NULL);

  51.         pthread_join(tid[1], NULL);
  52.         return 0;
  53. }
复制代码

论坛徽章:
0
3 [报告]
发表于 2007-11-25 15:03 |只看该作者
线程core dump时,你的USR信号是发不出去的。正确的方法是拦截SIGSEGV.

论坛徽章:
0
4 [报告]
发表于 2007-11-26 07:56 |只看该作者
呵呵,就是需要SIGUSR1发不出去,这样定时器才会超时,然后去重新拉起线程:)
SIGUSR1信号相当于被监视线程的心跳,心跳没有了,当然就是出问题了。

论坛徽章:
0
5 [报告]
发表于 2008-11-04 17:53 |只看该作者
但如果test1线程的执行时间长度不确定,有可能出现执行时间大于CHECK_THREAD_TIME的情况, 本例程似乎就要值得深入考虑了,
比如,可能会创建多个执行test1的线程实例;超时时钟会总是小于CHECK_THREAD_TIME等。 那么LZ怎么解决这个问题呢?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP