【问题标题】:two calls to timer_settime produce an error两次调用 timer_settime 产生错误
【发布时间】:2013-10-16 02:49:00
【问题描述】:

我定义并从 main 调用函数 initialize_timer 两次。 成功或失败取决于我两次调用同一函数的顺序。 也就是说,当我从 initialize_timer 调用 timer_settime 时,它​​第一次返回 0。然后,第二次返回 -1。

所以重申一下:如果我调用函数 initialize_timer 两次,对函数 timer_settime 的调用返回错误 1 ​​。 如果我只是颠倒两个调用的顺序(见下面的 main),那么它会返回没有错误(0 作为返回值)。

由于函数initialize_timer中的所有变量都是局部变量,我猜错误是我在main中调用calloc的方式。

谁能告诉我这个错误是什么?

为什么我的 initialize_timer 函数中对函数 timer_setttime 的第二次调用失败了?

提前致谢。

void initialize_timer(timer_t * tid, int seconds)
{    
    struct itimerspec * ts;
    struct sigaction *  sa;
    struct sigevent *  sev;
    ts = malloc(sizeof(struct itimerspec));
    sa = malloc(sizeof(struct sigaction));
    sev = malloc(sizeof(struct sigevent));
    if (tid == NULL)
        fprintf(stderr,"malloc");

        /* Establish handler for notification signal */

    sa->sa_flags = SA_SIGINFO;
    if(seconds == 2){
        sa->sa_sigaction = producer;
        printf("producer was created\n");
    }
    if(seconds == 6){
        sa->sa_sigaction = consumer;
        printf("consumer was created\n");
    }
    sigemptyset(&sa->sa_mask);
    if (sigaction(TIMER_SIG, sa, NULL) == -1)
        fprintf(stderr,"sigaction");

    /* Create and start one timer for each command-line argument */

    sev->sigev_notify = SIGEV_SIGNAL;    /* Notify via signal */
    sev->sigev_signo = TIMER_SIG;        /* Notify using this signal */

    itimerspec( ts, seconds);

    sev->sigev_value.sival_ptr = &tid;
    /* Allows handler to get ID of this timer */

    if (timer_create(CLOCK_REALTIME, sev, tid) == -1)
        fprintf(stderr,"timer_create");

    int error=timer_settime(tid, 0, ts, NULL) == -1;
    if (error!=0)
        fprintf(stderr,"error timer_settime");

}


int main(int argc, char *argv[])
{
    pthread_t t1, t2;
    int s = 0;
    timer_t *tidlist;
    tidlist = calloc(2, sizeof(timer_t));
    if (tidlist == NULL)
        fprintf(stderr, "malloc");

    create_threads(&t1, &t2);

    initialize_timer(tidlist + 1, 6); //initilize timer for consumer
    initialize_timer(tidlist, 2); //initilize timer for producer

    s = pthread_join(t1, NULL);
    if (s != 0)
        fprintf(stderr, "pthread_join");
    s = pthread_join(t2, NULL);
    if (s != 0)
        fprintf(stderr, "pthread_join");

    printf("glob = %d\n", glob);
    return 1;
}


void itimerspec(struct itimerspec *tsp, int seconds){
    tsp->it_value.tv_sec = seconds;
    tsp->it_value.tv_nsec = 0;
    tsp->it_interval.tv_sec = seconds;
    tsp->it_interval.tv_nsec = 0;
}

【问题讨论】:

  • 您可能希望将对fprintf(stderr, <error message)的调用替换为perror(<error message>),以接收有关失败原因的更详细信息。
  • itimerspec() 的代码似乎也相关。
  • if(tid == NULL) fprintf(stderr, "malloc")initializer_timer 中似乎也不对,因为 tid 是从外部给出的。您应该检查每个 malloc 中的 tssasev
  • 您是否知道您只能为同一信号安装一个信号处理程序(只有最后一个有效)? TIMER_SIG 是什么?

标签: c++ c multithreading posix


【解决方案1】:

基本上有两个错误:

  1. 您在同一个线程(主线程)中调用了两次sigaction。这意味着您将只安装一个信号处理程序(最后一个)。

  2. 您将 timer_settime 作为第一个参数提供 timer_t *(指针)而不是 timer_t。您应该在编译器中启用警告。 即使你给的不是tid,而是*tid,你也会在这两种情况下给它相同的值,因为你的tidlist是由calloc创建的,所以tidlist[0] == tidlist[1] == 0

【讨论】:

  • tidlist[0]==tidlist[1]==0 但后来,在初始化计时器时,我这样做: timer_create(CLOCK_REALTIME, sev, tid) 所以它初始化了 tidlist[0] 或 tidlist[ 1]取决于我传递给函数的内容。所以我不确定你在第二点上是否正确。但是第一点(你在上面说)是我的代码工作的原因。非常感谢
  • 我没有时间编辑我的评论。不,你也适合第二点。没有在 settime 取消引用 tid 是一个严重的错误。但是为什么 gcc 没有抱怨呢?我用 -Wall 标志编译了代码
  • 这看起来很奇怪,您可能需要检查 timer_t 的定义。
猜你喜欢
  • 1970-01-01
  • 2018-07-17
  • 2012-02-20
  • 1970-01-01
  • 1970-01-01
  • 2018-11-29
  • 1970-01-01
  • 2017-02-20
  • 2021-11-16
相关资源
最近更新 更多