【问题标题】:Is it possible to have multiple timers in a multithreaded application in C Linux?在 C Linux 中的多线程应用程序中是否可以有多个计时器?
【发布时间】:2015-07-02 05:16:59
【问题描述】:

我正在编写一个简单的测试来分析多线程应用程序在使用 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;
}

【问题讨论】:

  • man timer_create: [...]The kernel preallocates a "queued real-time signal" for each timer created using timer_create(). Consequently, the number of timers is limited by the RLIMIT_SIGPENDING resource limit (see setrlimit(2)).[...]

标签: c linux timer pthreads


【解决方案1】:

好的,所以我发现了我的错误。我没有取消对计时器指针的引用。 在函数threadTask中,具体在timer_settime的第一个参数应该是*threadParams-&gt;timer,重点是*。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-15
    • 2013-07-13
    • 1970-01-01
    • 1970-01-01
    • 2016-06-11
    • 2014-06-01
    相关资源
    最近更新 更多