免费注册 查看新帖 |

Chinaunix

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

对于在用户态陷入死循环的线程是不是毫无办法了? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-10-21 09:18 |只看该作者 |倒序浏览
linux的多线程编程中遇到问题了,如果我检测到某个线程可能进入了死循环,想对它进行操作,(不是要停止它,因此不能pthread_cancel),
发现通过给它发信号的方式不行,因为它只会在从内核态返回用户态的时候才去检查并且处理信号,而现在永远也进不了内核态了,
请教大侠,这种情况怎么办?除了杀掉他,还能有什么办法让他停止执行死循环代码吗?

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
2 [报告]
发表于 2008-10-21 09:33 |只看该作者
原帖由 acewind 于 2008-10-21 09:18 发表
发现通过给它发信号的方式不行,因为它只会在从内核态返回用户态的时候才去检查并且处理信号,而现在永远也进不了内核态了,

我不相信 Linux 的线程实现真这么弱智

论坛徽章:
0
3 [报告]
发表于 2008-10-21 10:04 |只看该作者

回复 #2 MMMIX 的帖子

虚心请教一下,该怎么办?

论坛徽章:
0
4 [报告]
发表于 2008-10-21 11:42 |只看该作者
按理说,每次时钟中断返回也会检查是否有信号等待处理,但是就是没触发

论坛徽章:
11
技术图书徽章
日期:2014-03-01 14:44:34天蝎座
日期:2014-05-21 22:11:59金牛座
日期:2014-05-30 17:06:14
5 [报告]
发表于 2008-10-21 11:42 |只看该作者
发现通过给它发信号的方式不行,因为它只会在从内核态返回用户态的时候才去检查并且处理信号,而现在永远也进不了内核态了

请问这是何处的理论?

你的想法和前段时间在C++版看到的“如何屏蔽段错误让程序继续运行?”性质相似。线程进入死循环明显是编程逻辑上的错误,即使通过信号跳出(确实可以办到),还不是治标不治本吗?

论坛徽章:
0
6 [报告]
发表于 2008-10-21 13:04 |只看该作者
是这样的,我的程序里面有一个死循环检测的功能,可以通过CPU的占有率检测到某一个线程有可能发生了死循环
然后我想知道这个线程在什么地方发生了死循环

于是我打算通过发信号的方式,发一个信号给这个发生死循环的线程,这样就能在它的上下文执行预先挂好的信号处理函数,在信号处理函数中回溯自己的堆栈,从而打印出函数调用链

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
7 [报告]
发表于 2008-10-21 14:14 |只看该作者
原帖由 acewind 于 2008-10-21 10:04 发表
虚心请教一下,该怎么办?

发信号。如果这样不行,把你的代码贴上来。

论坛徽章:
11
技术图书徽章
日期:2014-03-01 14:44:34天蝎座
日期:2014-05-21 22:11:59金牛座
日期:2014-05-30 17:06:14
8 [报告]
发表于 2008-10-21 14:56 |只看该作者
原帖由 acewind 于 2008-10-21 13:04 发表
是这样的,我的程序里面有一个死循环检测的功能,可以通过CPU的占有率检测到某一个线程有可能发生了死循环
然后我想知道这个线程在什么地方发生了死循环

于是我打算通过发信号的方式,发一个信号给这个发生 ...


呵呵,大概明白你想做什么了,是不是要实现类似下面的功能呢?
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
#include <execinfo.h>
#include <sys/select.h>

void sig_rt(int signo, siginfo_t *info, void *context);
void *trace(void *arg);
int Sleep(int sec);

int main(int argc, char *argv[])
{
    pthread_t tid;

    assert(pthread_create(&tid, NULL, trace, NULL) == 0);
    Sleep(3);
    pthread_kill(tid, SIGRTMAX);
    fprintf(stdout, "Send signal to thread: 0x%x\n", (unsigned int)tid);
    Sleep(9);

    return 0;
}

void sig_rt(int signo, siginfo_t *info, void *context)
{
    void *array[10];
    size_t size;
    char **strings;
    size_t i;

    if (signo == SIGRTMAX) {
       size = backtrace (array, 10);
       strings = backtrace_symbols (array, size);

       fprintf (stderr, "Thread(0x%x) obtained %zd stack frames.\n", (unsigned int)pthread_self(), size);

       for (i = 0; i < size; i++)
          fprintf (stderr, "%s\n", strings[i]);

       free (strings);
    } else {
        fprintf(stderr, "Another signo:%d", signo);
    }
}

void *trace(void *arg)
{
    sigset_t newset;
    struct sigaction act;

    sigemptyset(&newset);
    sigaddset(&newset, SIGRTMAX);
    pthread_sigmask(SIG_BLOCK, &newset, NULL);

    act.sa_sigaction = sig_rt;
    sigemptyset(&act.sa_mask);
    act.sa_flags = SA_SIGINFO;
    sigaction(SIGRTMAX, &act, NULL);
                                                                                      
    Sleep(6);
    pthread_sigmask(SIG_UNBLOCK, &newset, NULL);
    sleep(3);

    return NULL;
}

int Sleep(int sec)
{
    struct timeval sTime;

    sTime.tv_sec    = sec;
    sTime.tv_usec   = 0;
    return select(0, NULL, NULL, NULL, &sTime);
}

                                                                                         73,0-1        Bot

  1. 输出如下:
  2. Send signal to thread: 0xb7fcaba0
  3. Thread(0xb7fcaba0) obtained 5 stack frames.
  4. ./trace(sig_rt+0x22) [0x8048a71]
  5. /lib/tls/libpthread.so.0 [0x3dda90]
  6. ./trace(trace+0xb8) [0x8048bcd]
  7. /lib/tls/libpthread.so.0 [0x3d73cc]
  8. /lib/tls/libc.so.6(__clone+0x5e) [0x2511ae]
复制代码

[ 本帖最后由 timespace 于 2008-10-21 15:45 编辑 ]

论坛徽章:
0
9 [报告]
发表于 2018-10-11 13:06 来自手机 |只看该作者
不会死循环的,硬件中断保证调度器有机会执行,不然哪来的involuntary context switch
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP