写一个脚本 偶尔会出现进程卡住

t240034137 2014-07-17 09:36:14
我用php写了一个脚本,但是偶尔会出现进程卡住。(想问一下为啥有时候跑没问题,有时候又出现问题?)

白天还好,最烦的是晚上1,2点的时候。然后运维电话过来,你不得不起来kill 这个进程。

用了strace命令,给的结果是:

futex(0x2afe7c4f2240, FUTEX_WAIT_PRIVATE, 2, NULL



求问大大们,遇到这类问题如何解决。

我一个思路是,写一个守护脚本,遇到这个问题直接kill这个进程。但是感觉这个问题还是没解决。
...全文
382 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
lucky-lucky 2014-07-17
  • 打赏
  • 举报
回复
1.最好不要多线程,多线程时请使用互斥量。 2.把php脚本发上来瞧瞧呗。 3.保护住你调用的标准库函数。不要使用非线程安全函数。出现futex挂起一般是调用localtime,printf等非线程安全的C标准库所致,所以要获取时间等直接使用系统调用可避免该类问题。 4.shell脚本可以这样搞,下面程序每隔1分钟检测一次有无输入数据

root@primary:~/ci/cmake# cat monitor.c
#include <stdio.h>
#include <signal.h>         /* for SIG_ERR */
#include <unistd.h>
#include <time.h>   /*定时中断所需*/
#include <sys/time.h>
#include <sys/stat.h>   /*for S_IRUSR*/
#include <stdint.h>
#include <fcntl.h>
#include <assert.h>
#include <semaphore.h>

#define MAX_LINE 4096

#define CLOCKID CLOCK_REALTIME          /*定时中断的类型,默认为实时中断*/
#define SIG_TIMER SIGRTMIN

static timer_t timerid;                 /*POSIX定时器标识符*/
static sem_t cycle_mutex;

static int timer_init()
{
    struct sigevent sev;

    /*创建定时器*/
    sev.sigev_notify = SIGEV_SIGNAL;
    sev.sigev_signo = SIG_TIMER;
    sev.sigev_value.sival_ptr = &timerid;

    if (-1 == timer_create(CLOCKID, &sev, &timerid))
    {
        perror("创建定时器失败");
        return -1;
    }
}
static int timer_start(void)
{
    struct itimerspec its;

    /*设置定时器*/
    its.it_value.tv_sec = 60;   /*1min一次*/
    its.it_value.tv_nsec = 0;
    its.it_interval.tv_sec = its.it_value.tv_sec;
    its.it_interval.tv_nsec = its.it_value.tv_nsec;
    if (-1 == timer_settime(timerid, 0, &its, NULL))
    {
        perror("设置定时器失败");

        return -1;
    }
    return 0;
}

static void timer_action(int32_t sig, siginfo_t *si, void *uc)
{
    static int count = 0;
    static char buff[MAX_LINE] = {0};
    int ret = 0;

    ret = read(2,buff,MAX_LINE);
    if(-1 == ret)
    {
        count ++;
    }
    else
    {
        count = 0;
    }
    if(count > 10)
    {
        sem_post(&cycle_mutex);
    }
}

static int32_t sig_init(void)
{
    struct sigaction sa;

    /*初始化自定义信号*/
    sa.sa_flags = SA_SIGINFO;
    sa.sa_sigaction = timer_action;
    sigemptyset(&sa.sa_mask);

    if (sigaction(SIG_TIMER, &sa, NULL) == -1)
    {
        perror("初始化SIG_TIMER信号失败");
        return -1;
    }

    return 0;
}

int main()
{
    int ret = 0;
    /*set stdin to no block*/
    ret = fcntl(2,F_GETFL,0);
    if (-1 == ret)
    {
        perror("fcntl get stdout failed");
        return -1;
    }
    ret = fcntl(2,F_SETFL,ret | O_NONBLOCK);
    if (-1 == ret)
    {
        perror("fcntl set stdout failed");
        return -1;
    }
    ret = timer_init();
    assert(-1 != ret);

    ret = timer_start();
    assert(-1 != ret);

    ret = sig_init();
    assert(-1 != ret);

    ret = sem_init(&cycle_mutex,0,0);
    if (-1 == ret)
    {
        perror("初始化cycle_mutex失败");
        return -1;
    }

    do
    {
        ret = sem_wait(&cycle_mutex);
    }
    while(-1 == ret);

    printf("exit\n");

    return 0;
}
$gcc -lrt monitor.c -o monitor
$ps -ef | grep demo    # find demo pid 1111
$strace -fp 1111 | ./monitor | kill -9 1111 &
t240034137 2014-07-17
  • 打赏
  • 举报
回复
我是发错版了 还是没人在?
t240034137 2014-07-17
  • 打赏
  • 举报
回复
程序里面修复有: 1.请求url 接口的函数,都设置了2秒钟超时。 2.写文件已经上锁
ljc007 2014-07-17
  • 打赏
  • 举报
回复
教运维如何kill

18,772

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 专题技术讨论区
社区管理员
  • 专题技术讨论区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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