|
楼主 |
发表于 2007-11-25 10:36:37
|
显示全部楼层
解决了,上面的方法可以解决被监视线程终止的情况,但是不能解决线程被意外挂起的情况。
利用自定义信号和alarm就可解决挂起问题
解决方法是装载两个信号处理函数并设定alarm,一个处理alarm超时时,利用上面的方法重新启动一个线程C处理线程A的任务,并重新设定alarm;一个处理自定义信号,比如SIGUSR1,方法是在被监视线程A的处理函数中利用raise()函数定期发送SIGUSR1信号,该信号处理函数当捕捉到这个信号时就重设alarm值,这样新的值会代替久的值,那么时钟就不会超时,如果一段时间后没有收到这个信号,则被监视线程A就可能被挂起了,于是会执行处理alarm超时的处理函数。
到此,两个方法同时使用就可监视线程A,当A意外终止或被挂起的时候可以将它拉起。
P.S. 这里的监视线程A的处理函数要循环处理某些任务,被认为是将会一直运行的线程,所以任何情况的终止和挂起都是不被允许的。
测试代码如下:
- #include <stdio.h>
- #include <pthread.h>
- #include <signal.h>
- #include <time.h>
- #define CHECK_THREAD_TIME 60
- static pthread_t tid[2];
- static void test1()
- {
- while(1) {
- printf("thread1 continue, tid[%d]\n", pthread_self());
- raise(SIGUSR1);
- sleep(5);
- }
- }
- static void test2()
- {
- while(1) {
- pthread_join(tid[0], NULL);
- printf("thread2 continue, tid[%d]\n", pthread_self());
- pthread_create(&tid[0], NULL, (void *(*)(void *))test1, NULL);
- }
- }
- static void
- overtime_handler(int signo)
- {
- time_t tm;
- //time alarm
- printf("abnormal: thread has been hanged, time[%s], restart...\n", ctime(&tm));
- pthread_create(&tid[0], NULL, (void *(*)(void *))test1, NULL);
- alarm(CHECK_THREAD_TIME);
- }
- static void
- resetalarm_handler(int signo)
- {
- int ret;
- ret = alarm(CHECK_THREAD_TIME);
- printf("oh yeah! thread is still running, after [%d] seconds alarm will overtime\n", ret);
- }
- int main()
- {
- int ret;
- struct sigaction sa;
- memset(&sa, 0x0, sizeof(sa));
- sa.sa_handler = overtime_handler;
- sigaction(SIGALRM, &sa, NULL);
- sa.sa_handler = resetalarm_handler;
- sigaction(SIGUSR1, &sa, NULL);
- alarm(CHECK_THREAD_TIME);
- pthread_create(&tid[0], NULL, (void *(*)(void *))test1, NULL);
- pthread_create(&tid[1], NULL, (void *(*)(void *))test2, NULL);
- pthread_join(tid[1], NULL);
- return 0;
- }
复制代码 |
|