是否可以在C Linux中的多线程应用程序中使用多个计时器?

时间:2015-07-01 21:07:41

标签: c linux timer pthreads

我正在编写一个简单的测试来分析使用POSIX定时器时多线程应用程序的行为。
我正在创建3个线程,3个计时器,3个事件和3个timerspecs。

我要做的是让每个线程设置一个计时器,等待计时器到期(释放一个不安全的锁)并完成线程。
但是,当我运行以下程序时,只有第一个计时器到期,这让我相信每个进程可能不可能有多个计时器。有什么不对吗?

handle(union sigval params)是每个计时器到期时的回调
threadTask(void *params)是每个线程执行的回调。

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <pthread.h>

typedef struct TH_PARAMS
{
    uint threadNum;
    pthread_t tid;
    timer_t *timer;
    struct sigevent *event;
} ThreadParams_t;

static timer_t timers[3];
static struct itimerspec timeToWait[3];
static struct sigevent events[3];
static ThreadParams_t thParams[3];
static char wait[3];

static void handle(union sigval params)
{
    ThreadParams_t *threadParams = (ThreadParams_t *) params.sival_ptr;
    printf("Timer %d expired. Thread num which sent %d. Thread %ld. Pthread %ld.\n",
       *((int*) *(threadParams->timer)), threadParams->threadNum,
       syscall(SYS_gettid), pthread_self());
    wait[threadParams->threadNum] = 0;
}

static void *threadTask(void *params)
{
    ThreadParams_t *threadParams = (ThreadParams_t *) params;

    printf("Thread num %d. Thread %ld. Pthread %ld.\n",
       threadParams->threadNum, syscall(SYS_gettid),
       pthread_self());

    if (0 != timer_settime(threadParams->timer, 0, &timeToWait[threadParams->threadNum], NULL))
    {
    printf("Failed to set timers. Error %d.\n", errno);
    pthread_exit(NULL);
    }

    while(wait) sleep(1);

    pthread_exit(NULL);
}

int main()
{
    int i;

    printf("Main thread started. Thread: %ld. Pthread: %ld\n", syscall(SYS_gettid), pthread_self());

    for (i = 0; i < 3; ++i)
    {
    timeToWait[i].it_value.tv_sec = 2;
    timeToWait[i].it_value.tv_nsec = 0;
    timeToWait[i].it_interval.tv_sec = 0;
    timeToWait[i].it_interval.tv_nsec = 0;

    events[i].sigev_notify = SIGEV_THREAD;
    events[i].sigev_notify_function = handle;
    events[i].sigev_value.sival_ptr = &thParams[i];

    if (0 != timer_create(CLOCK_MONOTONIC, &events[i], &timers[i]))
    {
        printf("Failed to create timers. Error %d.\n", errno);
        return 1;
    }

    wait[i] = 1;

    thParams[i].threadNum = i;
    thParams[i].event = &events[i];
    thParams[i].timer = &timers[i];

    if (0 != pthread_create(&thParams[i].tid, NULL, threadTask, (void *) &thParams[i]))
    {
        printf("Failed to create thread. Error %d.\n", errno);

        for (i = 0; i < 3; ++i)
        {
        if (timers[i])
        {
            timer_delete(timers[i]);
        }
        }

        return 1;
    }
    }

    for (i = 0; i < 3; ++i)
    {
    pthread_join(thParams[i].tid, NULL);
    }

    for (i = 0; i < 3; ++i)
    {
    if (timers[i])
    {
        timer_delete(timers[i]);
    }
    }

    printf("Main thread finished. Thread: %ld.\n", syscall(SYS_gettid));

    return 0;
}

1 个答案:

答案 0 :(得分:2)

好的,所以我发现了自己的错误。我没有取消引用计时器指针。 在函数threadTask中,特别是在timer_settime中,第一个参数应为*threadParams->timer,强调*。